Javascript 何时根据来自redux的数据更新本地反应状态?

Javascript 何时根据来自redux的数据更新本地反应状态?,javascript,reactjs,redux,architecture,react-redux,Javascript,Reactjs,Redux,Architecture,React Redux,假设我的用例是打印一个帖子列表。我有以下反应组件 class App extends Component { constructor(props) { super(props); this.state = { loaded: !!(props.posts && props.posts.length) }; } componentDidMount() { this.st

假设我的用例是打印一个帖子列表。我有以下反应组件

class App extends Component {
    constructor(props) {
        super(props);
        this.state = {
            loaded: !!(props.posts && props.posts.length)
        };
    }

    componentDidMount() {
        this.state.loaded ? null : this.props.fetchPosts();
    }

    render() {
        return (
            <ul>
                {this.state.loaded
                    ? this.props.posts.length
                        ? this.props.posts.map((post, index) => {
                                return <li key={index}>{post.title}</li>;
                          })
                        : 'No posts'
                    : 'Loading'}
            </ul>
        );
    }
}
这将设置本地状态,最初将显示
微调器/加载器
,然后显示
发布
无发布
。然而,据我所知,React文档不鼓励
组件中的
设置状态
,因为
生命周期
钩子将在React 16中多次调用,也不推荐使用

那么,我应该在哪个生命周期钩子中更新本地状态?

  • 只在Redux中维护加载机制是否更好

    class App extends Component {
        constructor(props) {
            super(props);
        }
    
        compomentDidMount() {
            this.props.loaded ? null : this.props.fetchPosts();
        }
    
        render() {
            return (
                <ul>
                    {this.props.loaded
                        ? this.props.posts.length
                            ? this.props.posts.map((post, index) => {
                                    return <li key={index}>{post.title}</li>;
                            })
                            : 'No posts'
                        : 'Loading'}
                </ul>
            );
        }
    }
    
    类应用程序扩展组件{
    建造师(道具){
    超级(道具);
    }
    componentdidmount(){
    this.props.loaded?null:this.props.fetchPosts();
    }
    render(){
    返回(
    
      {this.props.loaded ?这个.props.posts.length ?此.props.posts.map((post,index)=>{ 返回
    • {post.title}
    • ; }) :“没有帖子” :“正在加载”}
    ); } }

  • 这里所有的东西都只在Redux商店中维护。如果有其他更好的方法,我很想知道。谢谢

    建议的解决方案是将其移动到
    MapStateTrops
    。大多数情况下,当您需要来自存储的数据(这里是
    posts
    )或来自存储的数据(这里是
    load
    )时,
    MapStateTrops
    是正确的注入位置。让从存储中获取数据的组件尽可能保持沉默通常是一个好主意。此外,将状态保存在从存储派生的组件中也违反了单一真实源原则,因为如果您不注意,它可能会失去同步:

    class App extends Component {
        render() {
            const {loading, posts} = this.props;
    
            if (loading) return 'Loading';
    
            if (!posts.length) return 'No Posts';
    
            return (
                <ul>
                    {posts.map((post, index) => (
                        <li key={index}>{post.title}</li>;
                    ))}
                </ul>
            );
        }
    }
    
    const mapStateToProps = ({posts}) => ({
        posts
        loading: !posts,
    });
    
    export default connect(mapStateToProps, /* mapDispatchToProps */)(App);
    
    类应用程序扩展组件{
    render(){
    const{loading,posts}=this.props;
    如果(装载)返回“装载”;
    如果(!posts.length)返回'No posts';
    返回(
    
      {posts.map((post,index)=>(
    • {post.title}
    • ; ))}
    ); } } 常量mapStateToProps=({posts})=>({ 帖子 加载:!posts, }); 导出默认连接(mapStateToProps,/*mapDispatchToProps*/)(应用程序);
    建议的解决方案是将其移动到
    MapStateTops
    。大多数情况下,当您需要来自存储的数据(这里是
    posts
    )或来自存储的数据(这里是
    load
    )时,
    MapStateTrops
    是正确的注入位置。让从存储中获取数据的组件尽可能保持沉默通常是一个好主意。此外,将状态保存在从存储派生的组件中也违反了单一真实源原则,因为如果您不注意,它可能会失去同步:

    class App extends Component {
        render() {
            const {loading, posts} = this.props;
    
            if (loading) return 'Loading';
    
            if (!posts.length) return 'No Posts';
    
            return (
                <ul>
                    {posts.map((post, index) => (
                        <li key={index}>{post.title}</li>;
                    ))}
                </ul>
            );
        }
    }
    
    const mapStateToProps = ({posts}) => ({
        posts
        loading: !posts,
    });
    
    export default connect(mapStateToProps, /* mapDispatchToProps */)(App);
    
    类应用程序扩展组件{
    render(){
    const{loading,posts}=this.props;
    如果(装载)返回“装载”;
    如果(!posts.length)返回'No posts';
    返回(
    
      {posts.map((post,index)=>(
    • {post.title}
    • ; ))}
    ); } } 常量mapStateToProps=({posts})=>({ 帖子 加载:!posts, }); 导出默认连接(mapStateToProps,/*mapDispatchToProps*/)(应用程序);

    2是正确的。最好只在Redux中维护状态。否则,此组件有两个单独的状态

    2是正确的。最好只在Redux中维护状态。否则,此组件有两个单独的状态

    你不能简单地检查
    render
    方法中的
    posts
    而不保持内部
    loaded
    状态吗?@devserkan你的意思是检查
    posts
    是否存在,以及是否有
    posts
    长度?是的。实际上,在第二个示例中,您正在做一件类似的事情,但是加载了什么
    道具?是的,您似乎可以只检查posts道具的状态。添加一个额外的状态层并没有多大意义,因为真理的标准来源是posts道具。一般来说,状态越多,事情就越复杂。@devserkan@adam thomas我可以像检查
    props.posts&&props.posts.length
    那样检查道具,然后显示
    posts
    else
    加载
    。但是,当没有找到
    帖子时,可能会出现这种情况?(空API响应)您不能简单地检查
    render
    方法中的
    posts
    而不保持内部
    loaded
    状态吗?@devserkan您的意思是检查
    posts
    是否存在以及是否存在
    posts
    长度?是的。实际上,在第二个示例中,您正在做一件类似的事情,但是加载了什么
    道具?是的,您似乎可以只检查posts道具的状态。添加一个额外的状态层并没有多大意义,因为真理的标准来源是posts道具。一般来说,状态越多,事情就越复杂。@devserkan@adam thomas我可以像检查
    props.posts&&props.posts.length
    那样检查道具,然后显示
    posts
    else
    加载
    。但是,当没有找到
    帖子时,可能会出现这种情况?(空API响应)我喜欢这种方法。只需
    加载
    ->
    加载
    。我想我明白了。对不起,你完全正确。更新了。@trixn所以,为了确认,
    posts
    最初将是
    空数组
    。因此,在装载时,
    装载
    将是
    真实的
    ,我们
    调度
    一个操作以
    获取
    并重新装载