我在看Pluralsight关于React的课程,老师说道具不应该被改变。我现在正在读一篇关于道具vs.国家的文章(uberVU/react-guide),它说
道具和状态更改都会触发呈现更新。
文章后面说:
Props(属性的缩写)是组件的配置,如果可以的话,是它的选项。它们是从上面接收的,是不可变的。
所以道具可以改变,但它们应该是不可变的?
什么时候应该使用道具,什么时候应该使用状态?
如果你有一个React组件需要的数据,它应该通过道具或设置在React组件通过getInitialState?
道具只是属性的简写。道具是组件之间相互交流的方式。如果你熟悉React,那么你应该知道道具是从父组件向下流动的。
还有一种情况是,你可以有默认的道具,这样即使父组件没有传递道具,道具也会被设置。
这就是为什么人们认为React具有单向数据流。这需要一些理解,我可能会在后面的博客中对此进行讨论,但现在只要记住:数据从父流向子。道具是不可变的(是指不变的)
所以我们很高兴。组件从父组件接收数据。都整理好了,对吧?
嗯,不完全是。当组件从父组件以外的对象接收数据时会发生什么?如果用户直接向组件输入数据呢?
这就是我们有状态的原因。
状态
道具不应该改变,所以状态上升。组件通常没有状态,因此被称为无状态。使用状态的组件称为有状态的。在聚会上随便说说你的小秘密,然后看着人们慢慢地离你而去。
所以使用状态是为了让组件可以在它所做的任何渲染之间跟踪信息。当你setState时,它更新状态对象,然后重新渲染组件。这非常酷,因为这意味着React会处理困难的工作,并且速度非常快。
作为状态的一个小例子,这里是一个搜索栏的片段(如果你想了解更多关于React的知识,值得看看这门课程)
Class SearchBar extends Component {
constructor(props) {
super(props);
this.state = { term: '' };
}
render() {
return (
<div className="search-bar">
<input
value={this.state.term}
onChange={event => this.onInputChange(event.target.value)} />
</div>
);
}
onInputChange(term) {
this.setState({term});
this.props.onSearchTermChange(term);
}
}
总结
道具和状态的作用类似,但使用方式不同。大多数组件可能是无状态的。
道具用于将数据从父组件传递给子组件或由组件本身传递。它们是不可变的,因此不会被改变。
State用于可变数据或将更改的数据。这对于用户输入特别有用。以搜索栏为例。用户将输入数据,这将更新他们所看到的内容。
props (properties的缩写)和state都是简单的JavaScript
对象。而两者都持有影响输出的信息
渲染,他们在一个重要的方面是不同的:道具被传递到
组件(类似于函数参数),而状态为
在组件中管理(类似于在组件中声明的变量
功能)。
所以简单的状态仅限于你当前的组件,但道具可以传递给任何组件你希望…你可以将当前组件的状态作为道具传递给其他组件……
同样在React中,我们有无状态的组件,它们只有道具,没有内部状态……
下面的例子展示了它们如何在你的应用程序中工作:
父组件(全状态组件):
class SuperClock extends React.Component {
constructor(props) {
super(props);
this.state = {name: "Alireza", date: new Date().toLocaleTimeString()};
}
render() {
return (
<div>
<Clock name={this.state.name} date={this.state.date} />
</div>
);
}
}
子组件(无状态组件):
const Clock = ({name}, {date}) => (
<div>
<h1>{`Hi ${name}`}.</h1>
<h2>{`It is ${date}`}.</h2>
</div>
);
一般来说,一个组件(父组件)的状态是子组件的prop。
State resides within a component where as props are passed from parent to
child.
Props are generally immutable.
class Parent extends React.Component {
constructor() {
super();
this.state = {
name : "John",
}
}
render() {
return (
<Child name={this.state.name}>
)
}
}
class Child extends React.Component {
constructor() {
super();
}
render() {
return(
{this.props.name}
)
}
}
在上面的代码中,我们有一个父类(parent),它的状态是name,它被传递给子组件(子类)作为道具,子组件使用{this.props.name}渲染它。
摘自:Andrea Chiarelli的书《开始React:用React简化前端开发工作流,增强应用程序的用户体验》:
Every React component has a props property. The purpose of this property is to collect data input passed to the component itself. JSX attribute is attached to a React element, a property with the same name is attached to the props object. So, we can access the passed data by using the attached property. In addition, the immutability of props allows us to think of components as pure functions, which are functions that have no side effects (since they don't change their input data). We can think of data passing from one component to another as a unidirectional data flow, from the parent component toward the child components. This gives us a more controllable system.
React provides a mechanism to support the automatic rendering of a component when data changes. Such a mechanism is based on the concept of state. React state is a property that represents data that changes over time. Every component supports the state property, but it should be used carefully. Components that store data that can change over time are said to be stateful components. A stateful component stores the state in the this.state property. To inform a component that the state has changed, you must use the setState() method. State initialization is the only case where you can assign a value to the this.state property without using setState().
setState()将新数据与已包含在状态中的旧数据合并,并覆盖先前的状态
setState()会触发render()方法的执行,所以永远不要显式地调用render()