我在React中创建了两个组件,<Search />
和<List />
这两个组件都是<App />
的子组件。
点击<Search />
中的按钮后,我想从API获取内容并在<List />
中显示结果。虽然我通过在<App />
内进行获取并将响应作为prop传递给<List />
来实现这一点,但我更愿意将fetch封装在<List />
中。
不幸的是,我很难找到一种方法来做到这一点。 'React方式'可能是通过一些聪明的道具传递来做到这一点,但我还没有找到一个巧妙的方法来做到这一点 - 即使是一个'shouldFetch'布尔值也需要在fetch之后重置,这似乎很麻烦并且会触发不必要的渲染。
This answer使用refs
来表示可能有用的类似内容,但实际上我有点犹豫不决,因为refs
似乎有点脏,根据React文档,因为他们“强制修改典型数据流之外的孩子”。
如果点击<List />
中的按钮后,如何指示我的<Search />
组件执行某些操作?
如果需要,我可以提供代码 - 但希望这个问题比我看起来更简单。
答案 0 :(得分:2)
一个自然的选择是在<App />
中创建一个状态布尔变量,当在<Search />
中按下按钮时触发,然后在<List />
中使用一些逻辑来获取布尔值时的数据州从false
转到true
。
例如:
class App extends React.Component {
constructor() {
super();
this.state = { fetchData: false }
}
render() {
return (
<div>
<Search onClick={() => this.setState({fetchData: true})} />
<List shouldFetch={this.state.fetchData} onFetch={() => this.setState({fetchData: false})} />
</div>
)
}
}
然后在您的<List />
组件中
class List extends React.Component {
componentWillReceiveProps(nextProps) {
if ( !this.props.shouldFetch && nextProps.shouldFetch ) {
// Fetch data here and set it in state, for example
// After fetch, don't forget to call onFetch() to reset the boolean
}
}
... // more code
}
虽然这样可行,但使用<App />
作为数据源并不错。这样,您可以抽象仅处理UI但没有网络逻辑的纯组件。这通常是一个很好的模型,可以帮助您在将来重用组件。
答案 1 :(得分:0)
这是使用商店的好时机,它会将您应用的整个状态保持为单个JS对象。 Flux,Redux是2个优秀的架构,可以补充React。基本上,您的组件会监听商店中的更改,当执行任何操作(进行api调用/单击等)时,商店会更新并且ui会更改。对于很多孩子来说,大规模的反应应用可能会非常混乱。
同样完全同意上述答案,让<List />
组件无状态,只能基于道具进行渲染。因此,在父<App/>
中编写函数并传递数据是一个好主意。