何时从在this.props和this.state中存储嵌套的组件变量切换

时间:2019-09-22 01:20:10

标签: javascript reactjs react-native

我要回到React并尝试复制instagram帖子。不变的变量,例如海报的名称,位置等,我想我对如何处理有很深的了解。我将它们放在array ( 0 => 'C5', 1 => 'C6', 2 => 'B3', 4 => 'B2', ) 的链中,因为从用户的角度来看它们将是不可变的。但是当涉及到“反应”之类的东西时,由于嵌套的 multi 个级别,我不确定何时将它们存储在this.propsthis.state中。

是否应该将所有嵌套组件的所有与我的反应数组/对象有关的数据保存在this.props中(如我在下面尝试做的那样)?还是将它们保留在this.state中,直到到达最低的子组件为止?

我没有任何用于提升状态的代码,因为我想确保自己的体系结构首先是正确的。

Home.js

this.props

Post.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>
    );
  }
}

ReactionList.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>
        );
    }
}

Reaction.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>
            )
        }
    }
}

1 个答案:

答案 0 :(得分:0)

如果您认为合理,则可以将POST_DATA完全存储在状态内,因为这将大大简化保存帖子信息的父组件和子帖子组件的行为。

例如,如果您希望帖子所有者能够编辑POST_DATA的正文或位置,而不仅仅是让用户编辑响应,该怎么办?或者,如果您希望反应可以被说成是一个单独的模式(当您单击帖子时)?

一种使该设计易于过时的方法是,将整个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
/>

为什么将网络数据作为不可变对象保存在应用程序/组件状态?

将发布数据保持为状态,作为不可变对象(在我使用immer.js的示例中)的好处是,例如,当您单击Instagram或Facebook的方式时, “爱”反应,针对您的反应发送API请求,并返回实时更新的反应值:

例如,如果我按“ Like(2)”,然后再按10个类似的按钮,API不会返回“ 3”(2 + 1),而是“ 13”(2 + 1 + 10)。用您当前的设计处理此问题将比我建议的设计花费更多的工作。

就个人而言,我宁愿使用Redux之类的库来获取应用程序状态,但是对于小型原型而言则没有必要。但是,如果涉及网络获取/更新,我建议无论项目大小如何,始终使用不可变对象。

希望这会有所帮助!