为什么我们有state
和props
?为什么我们不只有一个数据源?我想更新一个组件props
并让它重新渲染自身及其所有子组件。看起来很简单,但我不知道如何让组件更新它自己或它的父级的 props。
谢谢你的帮助。
为什么我们有state
和props
?为什么我们不只有一个数据源?我想更新一个组件props
并让它重新渲染自身及其所有子组件。看起来很简单,但我不知道如何让组件更新它自己或它的父级的 props。
谢谢你的帮助。
React 的哲学是 props 应该是不可变的和自顶向下的。这意味着父母可以将它喜欢的任何props值发送给孩子,但孩子不能修改自己的props。您所做的是对传入的props做出react,然后,如果您愿意,可以根据传入的props修改孩子的状态。
所以你永远不会更新你自己的props,或者父母的props。曾经。你只更新你自己的状态,并对父母给你的 prop 值做出react。
如果您希望在子节点上发生一个操作来修改状态上的某些内容,那么您要做的是将回调传递给它可以在给定操作上执行的子节点。这个回调然后可以修改父母的状态,然后可以在重新渲染时将不同的props发送给孩子。
在 React 中,props 向下流动,从parent 到 child。
这意味着当我们调用 时ReactDOM.render
,React 可以渲染根节点,传递任何props,然后忘记该节点。它完成了。已经渲染好了。
这发生在每个组件上,我们渲染它,然后沿着树向下移动,深度优先。
如果一个组件可以改变它的 props,我们将改变一个可以被父节点访问的对象,即使在父节点已经渲染之后。这可能会导致各种奇怪的行为,例如,auser.name
可能在应用程序的一个部分有一个值,而在不同的部分有一个不同的值,并且它可能会在下次触发渲染时更新自己。
// App renders a user.name and a profile
const App = (props) =>
React.createElement('div', null, [
props.user.name,
React.createElement(Profile, props)
])
// Profile changes the user.name and renders it
// Now App has the wrong DOM.
const Profile = ({user}) => {
user.name = "Voldemort" // Uh oh!
return React.createElement('div', null, user.name);
}
// Render the App and give it props
ReactDOM.render(
React.createElement(App, {user: {name: "Hermione"}}),
document.getElementById('app'))
);
我们呈现应用程序。它将“Hermione”输出到 Shadow DOM。我们渲染配置文件,它输出“伏地魔”。该应用程序现在是错误的。应该说“Voldemort”,因为user.name
是“Voldemort”,但是我们已经输出了“Hermione”,再改也来不及了。
该值在应用程序的不同部分会有所不同。
变异props将是一种双向绑定的形式。我们将修改树上另一个组件可能依赖的值。
Angular 1 有这个,你可以随时随地更改任何数据。为了工作,它需要一个周期性的 $digest。基本上,它会不断循环,重新渲染 DOM,直到所有数据都完成传播。这是 Angular 1 如此缓慢的部分原因。
在react,state
并props
服务于不同的目标:state
可以使组件保持一定的变化值,而props
对那些value观传播到孩子mecanism。
不允许孩子们自己改变他们通过 props 获得的值,因为 React 设计者发现以这种方式构建的应用程序更容易维护。他们的观点是,当只允许一个组件更新某个状态时,更容易发现谁更改了它,并找到了错误的根源。
Component 本身改变了它的状态,改变的不是它自己的,而是孩子的props。
<Parent>
<Child name={ this.state.childName } />
</Parent>
Parent 可以改变自己的 state 和改变 child 的名字,但是它会改变他的孩子的 props。
编辑1:为了从子级调用事件到其父级,您应该向子级传递一个事件处理程序,如下所示:
var Child = React.createClass({
render: function() {
return (<button onClick={ this.props.onClick }>Hey</button>);
}
});
var Parent = React.createClass({
onChildClick: console.log.bind(console), // will print the event..
render: function() {
return (<Child onClick={ this.onChildClick } />);
}
});
React.renderComponent(<Parent />, document.body);
在此代码中,当您单击子项的按钮时,它会将事件传递给其父项。传递事件的目的是解耦组件。也许在您的应用程序中您需要此特定操作,但在您将拥有的另一个应用程序中,您会以不同的方式使用它。
我的解决方案完全不同,但有些人可能会遇到它。在 Chrome Dev 工具上,它一直说我的 props 是只读的,当我尝试进一步传递它们时,我会得到一个错误。现在,原因是因为我没有调用render()
方法。我改为像这样调用我的组件:
const Navigation = () =>{
return (
<div className="left-navigation">
<ul>
<Link to='/dashboard'><li>Home</li></Link>
<Link to='/create-seedz'><li>Create Seedz</li></Link>
<Link to='/create-promotion'><li>Create Promotion</li></Link>
<Link to='/setting'><li>Setting</li></Link>
<SignOutButton />
</ul>
</div>
);
}
我添加了一个渲染方法,它解决了我能够传递props的问题:
class Navigation extends Component{
render(){
return (
<div className="left-navigation">
<ul>
<Link to='/dashboard'><li>Home</li></Link>
<Link to='/create-seedz'><li>Create Seedz</li></Link>
<Link to='/create-promotion'><li>Create Promotion</li></Link>
<Link to='/setting'><li>Setting</li></Link>
<SignOutButton user={this.props.user} signedOut={this.props.signedOut} authed={this.props.authed}/>
</ul>
</div>
);
}
}
希望这对某人有所帮助。