美文网首页
state和props

state和props

作者: 灭绝小师弟 | 来源:发表于2020-03-28 21:58 被阅读0次

state

state 是私有的,并且完全受控于当前组件。class组件才有state。

将函数组件转化成class组件

function Clock(props) {
  return (
    <div>
      <h1>Hello, world!</h1>
      <h2>It is {props.date.toLocaleTimeString()}.</h2>
    </div>
  );
}
#转化为class组件
class Clock extends React.Component {
  render() {
    return (
      <div>
        <h1>Hello, world!</h1>
        <h2>It is {this.props.date.toLocaleTimeString()}.</h2>
      </div>
    );
  }
}
  1. 创建一个与函数同名的类并且继承于 React.Component
  2. 添加一个空的 render() 方法, 将函数体移动到 render() 方法之中。
  3. render() 方法中使用 this.props 替换 props

每次组件更新时 render 方法都会被调用,但只要在相同的 DOM 节点中渲染 <Clock /> ,就仅有一个 Clock 组件的 class 实例被创建使用。这就使得我们可以使用如 state 或生命周期方法等很多其他特性。

在class组件中添加局部state

class Clock extends React.Component {
  constructor(props) {
    #Class 组件应该始终使用 props 参数来调用父类的构造函数。
    super(props);
    this.state = {date: new Date()};
  }

  render() {
    return (
      <div>
        <h1>Hello, world!</h1>
        <h2>It is {this.state.date.toLocaleTimeString()}.</h2>
      </div>
    );
  }
}

ReactDOM.render(
  <Clock />,
  document.getElementById('root')
);

将生命周期方法添加到 Class 中

在具有许多组件的应用程序中,当组件被销毁时释放所占用的资源是非常重要的。

class Clock extends React.Component {
  constructor(props) {
    super(props);
    this.state = {date: new Date()};
  }

  componentDidMount() {
    #当 `Clock` 组件第一次被渲染到 DOM 中的时候,就为其设置一个计时器。
    #这在 React 中被称为“挂载(mount)”。
    this.timerID = setInterval(
      () => this.tick(),
      1000
    );
  }

  componentWillUnmount() {
    #当 DOM 中 `Clock` 组件被删除的时候,应该清除计时器。
    #这在 React 中被称为“卸载(unmount)”。
    clearInterval(this.timerID);
  }

  tick = () => {
    this.setState({
      date: new Date()
    });
  }

  render() {
    return (
      <div>
        <h1>Hello, world!</h1>
        <h2>It is {this.state.date.toLocaleTimeString()}.</h2>
      </div>
    );
  }
}

执行顺序:

  1. 当 <Clock /> 被传给 ReactDOM.render()的时候,React 会调用 Clock 组件的构造函数。因为 Clock 需要显示当前的时间,所以它会用一个包含当前时间的对象来初始化 this.state。我们会在之后更新 state。
  2. 之后 React 会调用组件的 render() 方法。这就是 React 确定该在页面上展示什么的方式。然后 React 更新 DOM 来匹配 Clock 渲染的输出。
  3. 当 Clock 的输出被插入到 DOM 中后,React 就会调用 ComponentDidMount() 生命周期方法。在这个方法中,Clock 组件向浏览器请求设置一个计时器来每秒调用一次组件的 tick() 方法。
  4. 浏览器每秒都会调用一次 tick() 方法。 在这方法之中,Clock 组件会通过调用 setState() 来计划进行一次 UI 更新。得益于 setState() 的调用,React 能够知道 state 已经改变了,然后会重新调用 render() 方法来确定页面上该显示什么。这一次,render() 方法中的 this.state.date 就不一样了,如此以来就会渲染输出更新过的时间。React 也会相应的更新 DOM。
  5. 一旦 Clock 组件从 DOM 中被移除,React 就会调用 componentWillUnmount() 生命周期方法,这样计时器就停止了。

State的使用

  • 不要直接修改 State
this.state.comment = 'Hello'; // Wrong
#应该使用 setState():
this.setState({comment: 'Hello'}); // Correct
  • State 的更新可能是异步的

出于性能考虑,React 可能会把多个 setState() 调用合并成一个调用。因为 this.props 和 this.state 可能会异步更新,所以你不要依赖他们的值来更新下一个状态。

this.setState({
  counter: this.state.counter + this.props.increment,
}); // Wrong
#要解决这个问题,可以让 setState() 接收一个函数而不是一个对象。这个函数用上一个 state 作为第一个参数,将此次更新被应用时的 props 做为第二个参数:
this.setState((state, props) => ({
  counter: state.counter + props.increment
})); // Correct
  • State 的更新会被合并

调用 setState() 的时候,React 会把你提供的对象合并到当前的 state。这里的合并是浅合并。

constructor(props) {
    super(props);
    this.state = {
      posts: [],
      comments: []
    };
  }

  componentDidMount() {
    # 可以分别调用 setState() 来单独地更新它们
    fetchPosts().then(response => {
      this.setState({
        posts: response.posts
      });
    });

    fetchComments().then(response => {
      this.setState({
        comments: response.comments
      });
    });
  }

数据是自顶向下流动的

父组件或子组件都不能知道某个组件是有状态还是无状态,并且它们不应该关心某组件是被定义为一个函数还是一个class。
这就是为什么state通常被称为局部或封装。 除了拥有并设置它的组件外,其它组件不可访问。

组件可以选择把它的 state 作为 props 向下传递到它的子组件中。但子组件本身无法知道它是来自于父组件的 state、props、还是手动输入的。

这通常被称为“自顶向下”或“单向”数据流。 任何状态始终由某些特定组件所有,并且从该状态导出的任何数据或 UI 只能影响树中下方的组件。

props

state 和 props 主要的区别在于 props 是不可变的,而 state 可以根据与用户交互来改变。

  • props 验证

props 验证使用 propTypes,它可以保证我们的应用组件被正确使用,React.PropTypes 提供很多验证器 (validator) 来验证传入数据是否有效。当向 props 传入无效数据时,JavaScript 控制台会抛出警告。

let title = "测试";
// let title = 123;
class TestTitle extends React.Component {
  render() {
    return (
      <h1>Hello, {this.props.title}</h1>
    );
  }
}
 #当title不是string时(123),抛出警告。
TestTitle.propTypes = {
  title: PropTypes.string
};

ReactDOM.render(
    <TestTitle title={title} />,
    document.getElementById('root')
);

相关文章

  • React props

    React Props state 和 props 主要的区别在于 props 是不可变的,而 state 可以根...

  • React中的props和state

    props和state this.props 由 React 本身设定, 而 this.state 具有特殊的含义...

  • React内部状态state

    state   React组件的数据分为两种:props和state,props是组件的对外接口,state是组件...

  • state 和 props

    应该尽量让你的组件无状态化。 状态化指的是state来超级和变化的特性。 props应该是不会变化的特性。 比如这...

  • state和props

    state state 是私有的,并且完全受控于当前组件。class组件才有state。 将函数组件转化成clas...

  • React学习笔记2

    1.render函数对于props和state必须是纯函数 render函数不能改变props和state的属性,...

  • react native学习笔记6——Props和State

    Props(属性)和State(状态)是React Native中很重要的两个概念。使用Props和State,结...

  • ReactNative面试(1)

    1.props和state的区别? 现在我们来总结下,props与state的区别: props是指组件间传递的一...

  • react组件间通信

    react中的props和state props只读,用于组件之间传递信息,这个信息包括:数据和函数 state用...

  • React基础(5) -- Props

    state 和 props 主要的区别在于 props 是不可变的,而 state 可以根据与用户交互来改变。这就...

网友评论

      本文标题:state和props

      本文链接:https://www.haomeiwen.com/subject/vsfeuhtx.html