我正在重新使用 React 并尝试复制 Instagram 帖子。不会改变的变量,例如海报的名称、位置等,我想我对如何处理有充分的了解。我将它们保留在 this.props
链中,因为从用户 Angular 来看它们是不可变的。但当涉及到“ react ”之类的东西时,我不确定何时开始将它们存储在 this.state
与 this.props
中,因为多个 嵌套级别。
我是否应该将所有嵌套组件的与 react 数组/对象相关的数据保存在 this.state
中(正如我在下面尝试做的那样)一直向下?或者将它们保留在 this.props
中,直到我到达最低的子组件?
我没有任何用于提升状态的代码,因为我想首先确保我的架构是正确的。
Home.js
const POST_DATA = [
{
name: 'Outdoors Guy',
location: 'Yosemite, CA',
id: '123',
body: 'Hello world!',
image: 'https://someurl',
reactions: [
{
reaction: 'Like',
count: 2,
selected: true
},
{
reaction: 'Love',
count: 1,
selected: false
}
]
}
];
export default class HomeScreen extends React.Component {
constructor(props){
super(props)
this.state = {
posts: POST_DATA
}
}
render(){
return (
<View style={styles.container}>
<StatusBar barStyle="dark-content" />
<ScrollView>
<FlatList styles={styles.list}
data={this.state.posts}
renderItem={({ item }) =>
<Post
name={item.name}
location={item.location}
body={item.body}
image={item.image}
reactions={item.reactions}/>}
keyExtractor={item => item.id}/>
</ScrollView>
</View>
);
}
}
Post.js
export default class Post extends Component {
constructor(props){
super(props)
state = {
// should I be doing this?
reactions: this.props.reactions
}
}
render() {
return (
<View>
<View style={styles.postHeader}>
// Example of these two variables ending their chaining here
<Text style={styles.name}>{this.props.name}</Text>
<Text style={styles.location}>{this.props.location}</Text>
</View>
<Text style={styles.body}>{this.props.body}</Text>
<Image style={styles.image} source={{uri: this.props.image}}/>
// Heres where the confusion begins
<ReactionList list={this.props.reactions}/>
</View>
);
}
}
ReactionList.js
export default class ReactionList extends Component {
constructor(props){
super(props)
state = {
reactions: this.props.reactions
}
}
render() {
if (this.state.reactions === null)
{
return (
<View>
<AddReaction/>
<FlatList styles={styles.reactionList}
data={this.state.reactions}
renderItem={({ item }) =>
<Reaction
reaction={item.reaction}
count={item.count}
selected={item.selected}/>}
keyExtractor={item => item.id}/>
</View>
)
}
else{
return (
<View>
<AddReaction/>
</View>
)
}
}
}
Reaction.js
export default class Reaction extends Component {
constructor(props){
super(props)
state = {
// I understand these are not visible in the component
// but still want to track the data
count: this.props.count,
selected: this.props.selected
}
}
_onSelectPress () {
this.setState({
selected: !this.state.selected,
count: ++this.state.count
})
}
render() {
return (
<TouchableOpacity style={styles.reaction}
onPress={() => this._onSelectPress()}>
<Text style={styles.reactionText}>{this.props.reaction}</Text>
</TouchableOpacity>
);
}
最佳答案
如果您觉得有意义,您可以存储 POST_DATA
完全在状态内部,因为这将大大简化保存帖子信息的父组件和子帖子组件的行为。
例如,如果您不只是让用户编辑 react ,而是希望帖子所有者能够编辑 POST_DATA
的正文或位置,该怎么办? ?或者,如果您希望可以访问 react 计数,即一个单独的模式(当您单击帖子时)怎么办?
使该设计面向 future 的一种方法是,在保持简单的同时发送整个 POST_DATA
给您<Post>
组件,如果您不想使用 Redux 等库来处理状态,请向上提升回调以进行编辑:
Here's a simplified Codesandbox I did of this implementation .
<InstaPost
post={this.state.post} <-- this.state.post holds POST_DATA
handleReactionClick={this.handleReactionClick}
handleBodyEdit={this.handleBodyEdit} <-- if we decide to implement this later on
/>
为什么在应用/组件状态下将网络数据保存为不可变对象(immutable对象)?
将帖子数据作为不可变对象(immutable对象)(在我使用 immer.js 的示例中)保存在状态中的好处是,例如,如果 Instagram 或 Facebook 的工作方式是这样,当您单击“爱” react ,针对您的 react 发送 API 请求,并返回实时更新的 react 值:
例如,如果我按下“Like (2)”,然后又有 10 个人像之前一样按下,API 不会返回“3”(2+1),而是返回“13”(2 + 1 + 10)。使用您当前的设计来处理这个问题比我建议的设计需要更多的工作。
就我个人而言,我更喜欢使用 Redux 之类的库来获取应用程序状态,但对于小型原型(prototype)来说则没有必要。但是,如果涉及网络获取/更新,我建议始终使用不可变对象(immutable对象),无论项目大小如何。
希望这有帮助!
关于javascript - 何时从在 this.props 与 this.state 中存储嵌套组件变量切换,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58045336/