React说我们不应该尽可能使用git rm --cached <file>
,我注意到你不能使用refs进行浅层渲染测试,所以我试图在可能的情况下删除ref。我有一个像这样的子组件:
refs
然后我有一个需要调用这些方法的父组件。对于class Child extends React.Component {
play = () => {
//play the media
},
pause = () => {
//pause the media
},
setMedia = (newMedia) => {
//set the new media
}
}
我可以使用带有setMedia
的道具,并在新道具进入孩子时调用componentWillReceiveProps
。
使用setMedia
和play
函数,我无法做到这一点。
Ben Alpert回复了这个post并说:
通常,数据应该通过props传递到树下。除此之外还有一些例外(例如调用 .focus()或触发一次性动画并不真正改变状态)但随时都有你揭露了一个名为&#34; set&#34;的方法,道具通常是更好的选择。尝试做到这一点,以便内部输入组件担心它的大小和外观,以便它的祖先没有。
调用子函数的最佳方法是什么?
pause
和play()
方法可以从refs中调用,因为它们不像pause()
那样改变状态,并且对其他具有参数的函数使用props。通过传递方法名称来调用子函数,尽管这看起来很简单,而且复杂得多:
focus()
在子组件中执行此操作:class Child extends React.Component {
play = () => {
//play the media
},
pause = () => {
//pause the media
},
setMedia = (newMedia) => {
//set the new media
},
_callFunctions = (functions) => {
if (!functions.length) {
return;
}
//call each new function
functions.forEach((func) => this[func]());
//Empty the functions as they have been called
this.props.updateFunctions({functions: []});
}
componentWillReceiveProps(nextProps) {
this._callFunctions(nextProps.functions);
}
}
class Parent extends React.Component {
updateFunctions = (newFunctions) => this.setState({functions: newFunctions});
differentPlayMethod = () => {
//...Do other stuff
this.updateFunctions("play");
}
render() {
return (
<Child updateFunctions={this.updateFunctions}/>
);
}
}
这个问题是我们将一个方法暴露(复制)到另一个不应该真正了解它的组件......
这是最好的方法吗?
我目前正在使用方法2,我不是很喜欢它。
为了覆盖子函数,我也做了类似于上面的操作。我应该只使用refs吗?
答案 0 :(得分:2)
尝试从父级传递数据和函数,而不是调用子函数。除了组件,您还可以导出提供必要状态/函数的包装器或更高阶函数。
let withMedia = Wrapped => {
return class extends React.Component {
state = { playing: false }
play() { ... }
render() {
return (
<Wrapped
{...this.state}
{...this.props}
play={this.play}
/>
)
}
}
}
然后在您的父组件中:
import { Media, withMedia } from 'your-library'
let Parent = props =>
<div>
<button onClick={props.play}>Play</button>
<Media playing={props.playing} />
</div>
export default withMedia(Parent)
答案 1 :(得分:0)
尽可能保持状态本地化,但不要将其分布在多个组件上。如果您需要有关父级和子级当前是否正在播放的信息,请将状态保留在父级中。
这为您留下了更清晰的状态树和道具:
class Child extends React.Component {
render() {
return (
<div>
<button onClick={this.props.togglePlay}>Child: Play/Pause</button>
<p>Playing: {this.props.playing ? 'Yes' : 'No'}</p>
</div>
);
}
}
class Parent extends React.Component {
constructor(props) {
super(props);
this.togglePlay = this.togglePlay.bind(this);
this.state = {
playing: false
};
}
togglePlay() {
this.setState({
playing: !this.state.playing
});
}
render() {
return (
<div>
<button onClick={this.togglePlay}>Parent: Play/Pause</button>
<Child togglePlay={this.togglePlay} playing={this.state.playing} />
</div>
);
}
}
ReactDOM.render(
<Parent />,
document.getElementById('app')
);
&#13;
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id='app'></div>
&#13;