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,易发生数据混乱