玫瑰不香

导航

react - state与props

官网地址:https://zh-hans.reactjs.org/docs/glossary.html#components(组件)

       https://zh-hans.reactjs.org/docs/state-and-lifecycle.html#adding-local-state-to-a-class(state)

参考博客:https://blog.csdn.net/duola8789/article/details/90142891

state

1、简介(作用)

state(状态),是class的实例属性,是由组件本身管理的、用来跟踪数据发生变化状态改变的一种状态机(State Machine)

2、作用

控制本身的状态,完成对状态的行为控制、数据更新、界面渲染、记录自身数据变化等。简单的讲,就是记录内部状态

3、特性

可修改、可读

4、使用方式

(1)初始化方式

1)在constructor

添加一个class构造函数,然后在该函数中为this.state附初始值

class Clock extends React.Component {
  constructor(props) {  // constructor 是一种用于创建和初始化class创建的对象的特殊方法
    super(props);   //  super 继承父组件
    this.state = {date: new Date()};
  }

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

2)直接在Class中定义

class App extends React.Component {
  state = {
    loggedIn: false,
    currentState: "not-panic",
    someDefaultThing: this.props.whatever
  }

  render() {
    // whatever you like
  }
}

(2)调用方式

this.state.xxx

5、state正确使用方式

(1)不要直接修改 State

原因:不会重新渲染组件。  例:this.state.comment = 'Hello';   // Wrong

解决办法:使用setState。   例:this.setState({comment: 'Hello'});

(2)state的更新可能是异步的

React可能会将多个 setState 合并为一个调用。

因为 this.props 和 this.state 可能会异步更新,所以你不要依赖他们的值来更新下一个状态。

例如,此代码可能会无法更新计数器:

// Wrong
this.setState({
  counter: this.state.counter + this.props.increment,
});

解决办法:可以让setState接受一个函数而不是一个对象。这个函数用上一个 state 作为第一个参数,将此次更新被应用时的 props 做为第二个参数。

// Correct  &&  箭头函数
this.setState((state, props) => ({
  counter: state.counter + props.increment
}));

// Correct  &&  普通函数
this.setState(function(state, props) {
  return {
    counter: state.counter + props.increment
  };
});

(3)state的更新会被合并

当你调用setState时, React会把你提供的对象合并到当前的state

  例,你的state 包含几个独立的变量:

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

然后你可以分别调用 setState() 来单独地更新它们:

componentDidMount() {
    fetchPosts().then(response => {
      this.setState({
        posts: response.posts
      });
    });

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

这里的合并是浅合并,所以 this.setState({comments}) 完整保留了 this.state.posts, 但是完全替换了 this.state.comments

6、缺点

(1)带来管理的复杂性;

解决办法:

1)尽量多地写无状态组件,如此可降低代码维护的难度,也会在一定程度上增强组件的可复用性;

2)尽量编写函数式组件,函数式组件只有props没有state

props

1、简介

props,是React组件输入,父组件向子组件传递数据的媒介。

2、作用

用来父组件向子组件传递数据(定义外部接口)

3、特性

只读,不可修改

例:props.number = 42;  // 报错

所有 React 组件都必须像纯函数一样保护它们的 props 不被更改。

4、使用方式

(1)函数组件

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

  函数组件中,使用props方式是:props.xxx

(2)类组件

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

    render() {
         return <h1>Hello, {this.props.name}</h1>;
    }
} 

类组件中,使用props的方式是:this.props.xxx

5、props.children

  每个组件都可以获取到 props.children。它包含组件的开始标签和结束标签之间的内容。

例:

<Welcome>Hello world!</Welcome>

在 Welcome 组件中获取 props.children,就可以得到字符串 Hello world!

function Welcome(props) {
  return <p>{props.children}</p>;
}

对于 class 组件,请使用 this.props.children 来获取:

class Welcome extends React.Component {
  render() {
    return <p>{this.props.children}</p>;
  }
}

6、缺点

缺点:当父组件的传递的数据发生更新的时候不能更新到页面上

解决方法:

(1)componentWillReceiveProps  在组件接收到一个新的 props (更新后)时被调用。这个方法在初始化render时不会被调用。

(2)componentWillUpdate  在组件接收到新的props或者state但还没有render时被调用。在初始化时不会被调用。

注意:如果父组件传递过来的数据会发生更新,建议将props值的赋值给state,props发生更新就执行setState,及时更新页面。

如果父组件传递过来的数据不会发生更新,不建议将props的值赋给state,易发生数据混乱

 

posted on 2019-10-12 09:25  布娃娃  阅读(226)  评论(0编辑  收藏  举报