React入门系列一

近期开始入门react,对于我这样的前端码畜来讲
Q: 入门最好的方式是什么?(黑人问号脸)
A: 当然是看文档呀!!!
ps:我已经断断续续看了一星期的官方文档,总体来讲,我觉得文档写的很详细,详细的程度以致于我觉得有很多啰嗦的话(哈哈),所以一边敲案例,一边做自己的总结性的归纳。
附:大佬的对话,说的还是有道理的

image.png

jsx

1.在 JSX 当中的表达式要包含在大括号里

2.书写 JSX 的时候一般都会带上换行和缩进,这样可以增强代码的可读性

3.推荐在 JSX 代码的外面扩上一个小括号,这样可以防止 分号自动插入的 bug

4.JSX 标签是闭合式的,那么你需要在结尾处用 />, 就好像 XML/HTML 一样

//定义对象数据,给下面面类似"纯函数的组件"使用
const user = {
  firstName: 'Harper',
  lastName: 'Perez'
};
//jsx中调用此函数表达式
function formatName(user) {
  return user.firstName + ' ' + user.lastName;
};
// jsx换行缩进,增强可读性
const element = (
  <h1>
    Hello, {formatName(user)}!
  </h1>  {/* JSX标签是闭合式的 */}
);
// 渲染元素
ReactDOM.render(
  element,
  document.getElementById('root')
);

5.Babel 转译器会把 JSX 转换成一个名为 React.createElement() 的方法调用。

const element = <h1 className="greeting">Hello, world!</h1>;
//两种代码的作用是完全相同
const element = React.createElement(
  "h1",
  { className: "greeting" },
  "Hello, world!"
);

6.JSX 的特性更接近 JavaScript 而不是 HTML , 所以 React DOM 使用 camelCase 小驼峰命名 来定义属性的名称,而不是使用 HTML 的属性名称

//class 变成了 className,而 tabindex 则对应着 tabIndex
function App(props) {
  return (
    <div className="Comment" tabIndex="1">
      {/*
                         do something   
                    */}
    </div>
  );
}

元素渲染

  1. 元素是构成 React 应用的最小单位。
  2. 元素事实上只是构成组件的一个部分
  3. 在实际生产开发中,大多数 React 应用只会调用一次 ReactDOM.render()
  4. React DOM 首先会比较元素内容先后的不同,而在渲染过程中只会更新改变了的部分。

组件 & Props

  1. 组件从概念上看就像是函数,它可以接收任意的输入值(称之为“props”),并返回一个需要在页面上展示的 React 元素。

  2. 函数组件

    function Welcome(props) {
      return <h1>Hello, {props.name}</h1>;
    }
    
  3. 类组件

    class Welcome extends React.Component {
      render() {
        return <h1>Hello, {this.props.name}</h1>;
      }
    }
    
  4. 遇到的 React 元素都只是 DOM 标签,也可以是用户自定义的组件,当 React 遇到的元素是用户自定义的组件,它会将 JSX 属性作为单个对象传递给该组件,这个对象称之为“props”。

    class AppComponent extends React.Component {
      render() {
        return <h1>This is class define component: {this.props.name}</h1>;
      }
    }
    //组件名称必须以大写字母开头。<div /> 表示一个DOM标签,但 <App /> 表示一个组件
    ReactDOM.render(
      <AppComponent name="ReactApp" />,
      document.getElementById("root")
    );
    
  5. 通常,一个新的 React 应用程序的顶部是一个 App 组件。但是,如果要将 React 集成到现有应用程序中,则可以从下而上使用像 Button 这样的小组件作为开始,并逐渐运用到视图层的顶部。

    
      function Welcome(props){
            return <h1>Hello, {props.name}</h1>
        }
        class App extends React.Component {
            render() {
                return (
            {
                /*
                组件的返回值只能有一个根元素。这也是我们要用一个<div>来包裹所有<Welcome />元素的原因。
                */
             }
                    <div>
                        <h1>This is class define component: {this.props.name}</h1>
                        <Welcome name="1111" />
                        <Welcome name="2222" />
                        <Welcome name="3333" />
                    </div>
                )
            }
        }
        ReactDOM.render(<App name="ReactApp" />,document.getElementById("root"))
    

State & 生命周期

React 是非常灵活的,但它也有一个严格的规则:所有的 React 组件必须像纯函数那样使用它们的 props。何为纯函数? 字面意思就是给你什么返回什么,不关注函数内部的东西,引用函数式编程里面的一句话:所有纯函数必须遵守引用透明性

状态与属性十分相似,但是状态是私有的,完全受控于当前组件。

封装时钟(函数组件)

//封装时钟, 理想情况下,我们写一次 Clock 然后它能更新自身,为了实现这个需求,我们需要为Clock组件添加状态
function Clock(props) {
  return (
    <div>
      <h1>Hello, world!</h1>
      <h2>It is {props.date.toLocaleTimeString()}.</h2>
    </div>
  );
}
function tick() {
  ReactDOM.render(<Clock date={new Date()} />, document.getElementById("root"));
}
setInterval(tick, 1000);

类组件实现

Clock 现在被定义为一个类而不只是一个函数,使用类就允许我们使用其它特性,例如局部状态、生命周期钩子

//将函数转换为类
class Clock extends React.Component {
  render() {
    return (
      <div>
        <h1>Hello, world!</h1>
        <h2>It is {this.props.date.toLocaleTimeString()}.</h2>
      </div>
    );
  }
}

//为一个类添加局部状态State
class Clock extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      date: new Date(),
      name: this.props.name //将props存入state
    };
  }
  render() {
    return (
      <div>
        <h1>hello,React!</h1>
        <h2>this is Clock component:{this.state.date.toLocaleTimeString()}</h2>
        <h3>{this.props.name}</h3>
        <h3>{this.state.name}</h3>
      </div>
    );
  }
}

ReactDOM.render(
  <Clock name="这是我自定义的props:name" />,
  document.getElementById("root")
);

类组件中加入 React 的生命周期方法

  1. 在具有许多组件的应用程序中,在销毁时释放组件所占用的资源非常重要。
  2. 第一次加载到 DOM 中的时候叫作挂载,vue 中采用$mount("#app")
  3. OM 被移除的时候叫作卸载

我们可以在组件类上声明特殊的方法,当组件挂载或卸载时,来运行一些代码:

class Clock extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      date: new Date(),
      name: this.props.name
    };
  }
  //生命周期钩子
  componentDidMount() {
    this.timerID = setInterval(() => this.tick(), 1000);
  }
  //生命周期钩子
  componentWillUnmount() {
    clearInterval(this.timerID);
  }
  tick() {
    //调用 setState() 来调度UI更新
    this.setState({
      date: new Date()
    });
  }
  render() {
    return (
      <div>
        <h1>hello,React!</h1>
        <h2>this is Clock component:{this.state.date.toLocaleTimeString()}</h2>
        <h3>{this.props.name}</h3>
        <h3>{this.state.name}</h3>
      </div>
    );
  }
}

ReactDOM.render(
  <Clock name="这是我自定义的props:name" />,
  document.getElementById("root")
);

State 正确使用

1.不要直接更新状态

应当使用 setState(),构造函数是唯一能够初始化 this.state 的地方。

2.状态更新可能是异步的

React 可以将多个 setState() 调用合并成一个调用来提高性能。this.props 和 this.state 可能是异步更新的,你不应该依靠它们的值来计算下一个状态。请使用第二种形式的 setState() 来接受一个函数而不是一个对象。 该函数将接收先前的状态作为第一个参数,将此次更新被应用时的 props 做为第二个参数:

// es6大括号解释为块代码,如果箭头函数直接返回一个对象,必须在对象外面加上括号,否则报错
this.setState((prevState, props) => ({
  counter: prevState.counter + props.increment
}));

this.setState(function(prevState, props) {
  return {
    counter: prevState.counter + props.increment
  };
});
3.状态更新合并

当你调用 setState() 时,React 将你提供的对象合并到当前状态。

class CommentApp extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      user: "eastboat1",
      comments: [
        { id: 1, content: "这是评论1" },
        { id: 2, content: "这是评论2" },
        { id: 3, content: "这是评论3" }
      ]
    };
  }
  //生命周期钩子
  componentDidMount() {
    //模拟异步数据修改state ,独立更新对应的state
    setTimeout(() => {
      this.setState({
        user: "eastboat2"
      });
    }, 3000);
  }
  componentWillUnmount() {}
  render() {
    return (
      <div>
        <h2>this is my component:CommentApp</h2>
        <h2>{this.state.user}</h2>
        <h2>{this.props.UserName}</h2>
      </div>
    );
  }
}

ReactDOM.render(
  <CommentApp UserName="这是我自定义的props:UserName" />,
  document.getElementById("root")
);

数据流向(单向流)

组件可以选择将其状态作为属性传递给其子组件:这通常被称为自顶向下或单向数据流。 任何状态始终由某些特定组件所有,并且从该状态导出的任何数据或 UI 只能影响树中下方的组件。

事件处理

通常建议在构造函数中绑定或使用属性初始化器语法来避免这类

  1. React 事件绑定属性的命名采用驼峰式写法,而不是小写
  2. 如果采用 JSX 的语法你需要传入一个函数作为事件处理函数,而不是一个字符串(DOM 元素的写法)
//原生html中
<button onclick="handleChange">点击按钮</button>

//react
<button onClick={handleChange}>点击按钮</button>
  1. 在 React 中另一个不同是你不能使用返回 false 的方式阻止默认行为。你必须明确的使用 preventDefault
//类组件中 不能使用返回 false 的方式阻止默认行为
class App extends React.Component {
  render() {
    function handleClick(e) {
      e.preventDefault();
      console.log("The link was clicked.");
    }
    return (
      <a href="www.baidu.com" onClick={handleClick}>
        a标签
      </a>
    );
  }
}
类的方法
  1. 使用 React 的时候通常你不需要使用 addEventListener 为一个已创建的 DOM 元素添加监听器。你仅仅需要在这个元素初始渲染的时候提供一个监听器。
class Toggle extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      isToggleOn: true
    };
    this.handleClick = this.handleClick.bind(this);
  }
  //类方法,但是类的方法默认是不会绑定 this 的,需要上面的bind
  handleClick() {
    this.setState(prevState => ({
      isToggleOn: !prevState.isToggleOn
    }));
  }

  render() {
    return (
      <button onClick={this.handleClick}>
        {this.state.isToggleOn ? "ON" : "OFF"}
      </button>
    );
  }
}
属性初始化器语

这种语法确保this绑定在 handleClick 中

class LoggingButton extends React.Component {
  handleClick = () => {
    console.log("this is:", this);
  };
  render() {
    return <button onClick={this.handleClick}>Click me</button>;
  }
}
回调函数中使用箭头函数
class LoggingButton extends React.Component {
  handleClick() {
    console.log("this is:", this);
  }

  render() {
    return <button onClick={e => this.handleClick(e)}>Click me</button>;
  }
}
向事件处理程序传递参数
//二者等价
//箭头函数的方式,事件对象必须显式的进行传递
<button onClick={(e) => this.deleteRow(id, e)}>Delete Row</button>

//bind 的方式,事件对象以及更多的参数将会被隐式的进行传递
<button onClick={this.deleteRow.bind(this, id)}>Delete Row</button>

通过 bind 方式向监听函数传参,在类组件中定义的监听函数,事件对象 e 要排在所传递参数的后面

class App extends React.Component {
  constructor() {
    super();
    this.state = { name: "Hello world!" };
  }
  preventPop(name, e) {
    //事件对象e要放在最后
    e.preventDefault();
    alert(name);
  }
  render() {
    return (
      <div>
        <p>hello</p>
        <a
          href="https://reactjs.org"
          onClick={this.preventPop.bind(this, this.state.name)}
        >
          Click
        </a>
      </div>
    );
  }
}

条件渲染

if 条件判断

使用 JavaScript 运算符 if 或者条件运算符去创建元素来表现当前的状态

//组件一
function ComponentOne() {
  return <h1>this is component one</h1>;
}
//组件二
function ComponentTwo() {
  return <h1>this is component two</h1>;
}
//容器组件
function App(props) {
  const status = props.isLoginStatus;
  if (status) {
    return <ComponentOne />;
  } else {
    return <ComponentTwo />;
  }
}
使用元素变量存储元素
function LoginButton(props) {
  return <button onClick={props.onClick}>登录</button>;
}

function LogoutButton(props) {
  return <button onClick={props.onClick}>登出</button>;
}
class LoginControl extends React.Component {
  constructor(props) {
    super(props);
    this.handleLoginClick = this.handleLoginClick.bind(this);
    this.handleLogoutClick = this.handleLoginClick.bind(this);
    this.state = {
      isLoginStatus: false
    };
  }
  handleLoginClick() {
    //登录
    this.setState({
      isLoginStatus: true
    });
  }
  handleLogoutClick() {
    //登出
    this.setState({
      isLoginStatus: false
    });
  }

  render() {
    const status = this.state.isLoginStatus;
    let button; //创建变量存储组件元素
    if (status) {
      button = <LogoutButton onClick={this.handleLogoutClick} />;
    } else {
      button = <LoginButton onClick={this.handleLoginClick} />;
    }
    return <div>{button}</div>;
  }
}
与运算符 &&

在 JavaScript 中,true && expression 总是会返回 expression, 而 false && expression 总是会返回 false。如果条件是 true,&& 右侧的元素就会被渲染,如果是 false,React 会忽略并跳过它。

const arr = ["a", "b", "c"];
function App(props) {
  const list = props.list;
  return <div>{list.length > 0 && <h1>这是list列表</h1>}</div>;
}
ReactDOM.render(<App list={arr} />, document.getElementById("root"));
三目运算符
//文本渲染使用
return (
  <div>
    The user is <b>{isLoggedIn ? "currently" : "not"}</b> logged in.
  </div>
);
//组件渲染使用
return (
  <div>
    {isLoggedIn ? (
      <LogoutButton onClick={this.handleLogoutClick} />
    ) : (
      <LoginButton onClick={this.handleLoginClick} />
    )}
  </div>
);
阻止组件渲染
  1. 可以让 render 方法直接返回 null,而不进行任何渲染
  2. 在组件的 render 方法中返回 null 并不会影响组件的生命周期
function WarningBanner(props) {
  if (!props.warn) {
    return null;
  }

  return <div className="warning">Warning!</div>;
}

列表 && key

map() 函数
// map() 不会对空数组进行检测
// map() 不会改变原始数组。
const numbers = [1, 2, 3, 4, 5];
const doubled = numbers.map(number => number * 2);
// [2, 4, 6, 8, 10]
key 用作确定的标识
  1. 一个元素的 key 最好是这个元素在列表中拥有的一个独一无二的字符串。通常,我们使用来自数据 id 来作为元素的 key
  2. 如果列表项目的顺序可能会变化,我们不建议使用索引来用作 key 值,因为这样做会导致性能变差,还可能引起组件状态的问题
class App extends React.Component {
  constructor(props) {
    super(props);
  }
  render() {
    const list = this.props.listitem;
    const ListItem = list.map((val, index, arr) => {
      return <li key={index}>{val}</li>;
    });
    return (
      <div>
        <ul>{ListItem}</ul>
      </div>
    );
  }
}
const arr = ["a", "b", "c", "d", "e"];
ReactDOM.render(<App listitem={arr} />, document.getElementById("root"));
  1. 元素的 key 只有放在就近的数组上下文中才有意义。
function ListItem(props) {
  // 正确!这里不需要指定 key:
  return <li>{props.value}</li>;
}

function NumberList(props) {
  const numbers = props.numbers;
  const listItems = numbers.map(number => (
    // 正确!key 应该在数组的上下文中被指定
    <ListItem key={number.toString()} value={number} />
  ));
  return <ul>{listItems}</ul>;
}

const numbers = [1, 2, 3, 4, 5];
ReactDOM.render(
  <NumberList numbers={numbers} />,
  document.getElementById("root")
);
  1. key 只是在兄弟节点之间必须唯一

    数组元素中使用的 key 在其兄弟节点之间应该是独一无二的。然而,它们不需要是全局唯一的。当我们生成两个不同的数组时,我们可以使用相同的 key 值:

JSX 中嵌入 map()
function ListItem(props) {
  return <li>{props.value}</li>;
}
class App extends React.Component {
  constructor(props) {
    super(props);
  }
  render() {
    const list = this.props.listitem;
    return (
      <div>
        <ul>
          {/*此处是jsx中的写法*/
          list.map((val, index, arr) => (
            <ListItem value={val} key={index} />
          ))}
        </ul>
      </div>
    );
  }
}
const arr = ["a", "b", "c", "d", "e"];
ReactDOM.render(<App listitem={arr} />, document.getElementById("root"));

表单

在 React 里,HTML 表单元素的工作方式和其他的 DOM 元素有些不同,这是因为表单元素通常会保持一些内部的 state

受控组件

表单元素通常自己维护 state,并根据用户输入进行更新,而可变状态(mutable state)通常保存在组件的 state 属性中,并且只能通过使用 setState()来更新,两者结合起来,使得 React 的 state 成为“唯一数据源,渲染表单的 React 组件还控制着用户输入过程中表单发生的操作,这种表单输入元素就叫做“受控组件”。

class MyFormComponent extends React.Component {
  constructor(props) {
    super(props);
    this.state = { value: "初始化state内容" };
    this.handleChange = this.handleChange.bind(this);
    this.handleSubmit = this.handleSubmit.bind(this);
  }
  handleChange(e) {
    this.setState({
      value: e.target.value
    });
  }
  handleSubmit(e) {
    e.preventDefault();
    console.log(e.target);
    console.log(this.state.value);
  }
  render() {
    return (
      <form onSubmit={this.handleSubmit}>
        <input
          type="text"
          value={this.state.value}
          onChange={this.handleChange}
        />
        <input type="submit" value="提交" />
      </form>
    );
  }
}

ReactDOM.render(<MyFormComponent />, document.getElementById("root"));
textarea 标签

在 HTML 中, textarea 元素通过其子元素定义其文本,而在 React 中,textarea 使用 value 属性代替,和上面的 input 一样绑定 value 属性

select 标签

React 并不会使用 selected 属性,而是在根 select 标签上使用 value 属性

//可以将数组传递到 value 属性中,以支持在 select 标签中选择多个选项
<select multiple={true} value={['B', 'C']}>
处理多个输入

当需要处理多个 input 元素时,我们可以给每个元素添加 name 属性,并让处理函数根据 event.target.name 的值选择要执行的操作

状态提升

多个组件需要反映相同的变化数据,这时我们建议将共享状态提升到最近的共同父组件中去

  1. 在 React 应用中,任何可变数据应当只有一个相对应的唯一“数据源”
  2. 应当依靠自上而下的数据流,而不是尝试在不同组件间同步 state。

组合 VS 继承

推荐使用组合而非继承来实现组件间的代码重用

在 React 中没有“槽”这一概念的限制,你可以将任何东西作为 props 进行传递

  1. 使用一个特殊的 children prop 来将他们的子组件传递到渲染结果中
    function App(props) {
      return <div>{props.children} //渲染子组件</div>;
    }
    //组件中的子组件内容
    function ParentComponent() {
      return (
        <App>
          <p>这是子组件内容</p>
          <p>这是子组件内容</p>
          <p>这是子组件内容</p>
        </App>
      );
    }
    
  2. 少数情况下,你可能需要在一个组件中预留出几个“洞”。这种情况下,我们可以不使用 children,而是自行约定:将所需内容传入 props,并使用相应的 prop。
     function App(props) {
       return (
         <div>
             <div className='CommOne'>
                 { props.left }
             </div>
             <div className='CommTwo'>
                 { props.right }
             </div>
         </div>
       );
     }
     //  如  <leftComponent />  <rightComponent /> React 元素本质就是对象(object)
     function ParentComponent() {
       return (
         <App
             left={
               <leftComponent />
             }
             right={
               <rightComponent />
             }
         />
         );
     }
     ```
    **Props 和组合为你提供了清晰而安全地定制组件外观和行为的灵活方式。注意:组件可以接受任意 props,包括基本数据类型,React 元素以及函数**
    

如果你想要在组件间复用非 UI 的功能,我们建议将其提取为一个单独的 JavaScript 模块,如函数、对象或者类。组件可以直接引入(import)而无需通过 extend 继承它们

React 哲学

我们平时在公司中,都会和 UI 小姐姐(小哥哥)对接,做项目时首先拿到项目的 UI 设计稿,这时候我们就需要站在组件的维度去思考这个 UI 设计稿。

1.划分为组件层级

根据 UI 设计稿划分为组件层级,以合适的名称命名,UI(组件结构)和数据模型都会倾向于遵守相同的信息结构,所以 UI 和 JSON 数据模型一一对应

Q:如何确定应该将哪些部分划分到一个组件中呢?
A:可以将组件当作一种函数或者是对象来考虑,
  根据单一功能原则来判定组件的范围。
  也就是说,一个组件原则上只能负责一个功能。
2.编写静态的组件
  1. 先用已有的数据模型渲染一个不包含交互功能的 UI
  2. 最好将渲染 UI 和添加交互这两个过程分开,因为往往要编写大量代码,而不需要考虑太多交互细节,而添加交互功能时则要考虑大量细节,不需要编写太多代码
  3. 当你的应用比较简单时,使用自上而下的方式更方便;对于较为大型的项目来说,自下而上地构建,并同时为低层组件编写测试是更加简单的方式。
  4. state 代表了随时间会产生变化的数据,应当仅在实现交互时使用。所以构建应用的静态版本时,你不会用到它
3.确定所需的 state 的最小集合

通过问自己以下三个问题,你可以逐个检查相应数据是否属于 state

1.该数据是否是由父组件通过 props 传递而来的?如果是,那它应该不是 state。
2.该数据是否随时间的推移而保持不变?如果是,那它应该也不是 state。
3.你能否根据其他 state 或 props 计算出该数据的值?如果是,那它也不是 state。
4.确定 state 放置的位置

上面已经确定了应用所需的 state 的最小集合。接下来,我们需要确定哪个组件能够改变这些 state,或者说拥有这些 state。

1.找到根据这个 state 进行渲染的所有组件。
2.找到他们的共同所有者(common owner)组件(在组件层级上高于所有需要该 state 的组件)。
3.该共同所有者组件或者比它层级更高的组件应该拥有该 state。
4.如果你找不到一个合适的位置来存放该 state,就可以直接创建一个新的组件来存放该 state,并将这一新组件置。
5.于高于共同所有者组件层级的位置。
5.添加反向数据流( setState )

React 通过一种比传统的双向绑定略微繁琐的方法来实现反向数据传递。尽管如此,但这种需要显式声明的方法更有助于人们理解程序的运作方式。
我们通过 setState()函数让数据反向传递:处于较低层级的表单组件更新较高层级中的 state。

至此 react 文档基本核心内容已看完,再也不用担心被 T 掉了

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 196,264评论 5 462
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 82,549评论 2 373
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 143,389评论 0 325
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,616评论 1 267
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,461评论 5 358
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,351评论 1 273
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,776评论 3 387
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,414评论 0 255
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,722评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,760评论 2 314
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,537评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,381评论 3 315
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,787评论 3 300
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,030评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,304评论 1 252
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,734评论 2 342
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,943评论 2 336

推荐阅读更多精彩内容

  • 作为一个合格的开发者,不要只满足于编写了可以运行的代码。而要了解代码背后的工作原理;不要只满足于自己的程序...
    六个周阅读 8,408评论 1 33
  • HTML模版 之后出现的React代码嵌套入模版中。 1. Hello world 这段代码将一个一级标题插入到指...
    ryanho84阅读 6,206评论 0 9
  • 40、React 什么是React?React 是一个用于构建用户界面的框架(采用的是MVC模式):集中处理VIE...
    萌妹撒阅读 998评论 0 1
  • 1、什么是react React.js 是一个帮助你构建页面 UI 的库。React.js 将帮助我们将界面分成了...
    谷子多阅读 2,553评论 1 13
  • 最近看了一本关于学习方法论的书,强调了记笔记和坚持的重要性。这几天也刚好在学习React,所以我打算每天坚持一篇R...
    gaoer1938阅读 1,660评论 0 5