我有两个组件,父母和孩子,如下:
class Parent extends React.Component {
shuffle() {
...
}
blur() {
...
}
next() {
...
}
previous() {
...
}
render() {
return (
<Child Parent={this} />
);
}
}
class Child extends React.Component {
constructor(props) {
super();
this.state = {};
this._onShuffleClick = this._onShuffleClick.bind(props.Parent);
this._onPreviousClick = this._onPreviousClick.bind(props.Parent);
this._onNextClick = this._onNextClick.bind(props.Parent);
}
_onShuffleClick(event) {
event.preventDefault();
this.shuffled ? this.shuffle(false) : this.shuffle(true); // I can call parents method here as the 'this' context is the 'Parent'.
this.blur(event.target);
this.setState({test "test"}); //I can set the parents state here
}
_onPreviousClick(event) {
event.preventDefault();
this.previous();
this.blur(event.target);
}
_onNextClick(event) {
event.preventDefault();
this.next();
this.blur(event.target);
}
render() {
return (
<a className="shuffle" key={1} onClick={this._shuffleOnClick}>{this.props.Parent.props.html.shuffle}</a>,
<a className="previous" key={2} onClick={this._previousOnClick}>{this.props.Parent.props.html.previous}</a>,
<a className="next" key={3} onClick={this._nextOnClick}>{this.props.Parent.props.html.next}</a>,
);
}
}
将上下文('this'关键字)作为反模式传递? 是否设置了孩子的父母状态不好?
如果我这样做,那么我就不必向孩子传递很多个人道具,我也可以设置孩子的父母的状态。
答案 0 :(得分:2)
您可以与子组件中父级的state
进行交互,但可能与您尝试实现此方式的方式不同。
如果您想将父母的所有props
发送给孩子,您可以这样做:
<Child {...this.props} />
这样,您无需一次指定一个prop
个人;相反,您只需将它们全部发送出去。请查看传播运营商 here和here以获取更多信息。有关MDN的更多信息:
扩展语法允许在需要多个参数(用于函数调用)或多个元素(用于数组文字)或多个变量(用于解构赋值)的地方扩展表达式。
如果您想要从孩子那里访问或修改父母的state
,您必须稍微改变一下。通常,您将创建一个与父项中的state
进行此交互的函数,然后将该函数作为prop
发送给子项。像这样:
<强>父:强>
_modifyState = (bar) => {
this.setState({foo: bar});
}
.....
<Child modifyState={this._modifyState} />
儿童:强>
this.props.modifyState("Hello world!");
以上内容会将父项中的state.foo
设置为子组件中的字符串Hello world!
。
如果要访问所有state
个变量,可以将其作为prop
发送给子项(整个对象),然后使用一个函数(如上所述)修改整个状态(不只是一个属性) - 取决于你真正想要的东西。
答案 1 :(得分:1)
嗯,这主要是绕过道具的不好用法,你也可以选择{...props}
,我不想通过全名传递它,你也可以使用{{1} }。问题是,为什么你会提到父道具,这似乎是不好的做法,分而治之,只传递真正需要的道具,并且不要在你的孩子组件中假设某个父组件可用
当你传递事件处理程序时,让那些事件处理程序绑定到你当前的这个,但不要将它们绑定到一个预期的父项,就像这个例子
let { props } = this; let parentProps = props.Parent.props
var StyledButton = React.createClass({
propTypes: {
clickHandler: React.PropTypes.func.Required,
text: React.PropTypes.string.required
},
render: function() {
let { clickHandler, text } = this.props;
return <button type="button" onClick={clickHandler}>{text}</button>;
}
});
var MyForm = React.createClass({
click: function() {
alert('ouch');
},
render: function() {
return <fieldset>
<StyledButton clickHandler={this.click} text="Click me" />
</fieldset>
}
})
ReactDOM.render(
<MyForm />,
document.getElementById('container')
);
答案 2 :(得分:1)
是的,我认为你的代码是不好的做法。现在,您可以了解组件,了解使您的孩子不纯净的父组件。
当您的父实现更改时,子组件将因this.props.Parent.props.html.previous}
而中断。
我认为每个react组件都应该通过调用props传递的parent函数来更新父组件。
class Parent extends React.Component {
doSomethingBeacauseTheChildStateHasChanged() {
// function
}
render() {
<Child doSomething={doSomethingBeacauseTheChildStateHasChanged.bind(this)}/>
}
}
class Child extends React.Component {
render() {
<button onClick={this.props.doSomething}>Child button</button>
}
}
答案 3 :(得分:0)
注意:我不是专家和React初学者,将此视为意见而不是指南。
我认为是因为你迫使特定的实施。如果你想在GrandParent中使用这些方法,你会怎么做?如果你使用道具这个修改真的很容易,但是你的实现它会很痛苦。
还有一项名为PropTypes的功能。使组件可重用是非常棒的,但是如果你按照你的建议做的事情,那么你又不能使用它。
也许只是我,但这也造成了很大的混乱。你应该把你需要的一切都当成道具。
也像这样设置父状态
this.setState({test "test"}); //I can set the parents state here
对我来说似乎很糟糕。我宁愿从父作为prop传递一个函数,并在传递它之前绑定父类。
答案 4 :(得分:0)
您可以在Parent中触发一个功能。这是儿童与其父母沟通的正确方法。
class Parent extends React.Component {
shuffle(e) {
console.log(e.target);
return false;
}
render() {
return (
<Child onShuffle={this.shuffle} />
);
}
}
class Child extends React.Component {
render() {
return(
<a href='#' onClick={this.props.onShuffle}>Shuffle</a>
);
}
}
Child.propTypes = {
onShuffle: React.PropTypes.func
}