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

时间:2018-08-06 16:44:07

标签: javascript reactjs redux architecture react-redux

可以说我的用例是打印帖子列表。我有以下反应成分。

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

fetchPosts是一种操作,该操作进行API调用以从数据库中获取帖子,然后使用数据更新redux存储。现在,我的问题是

  1. 何时应根据道具更新本地React状态?

最初,this.props.posts将是undefined[],因此this.state.loaded将是false,我们将进行API调用来提取。一次,获取数据,然后将其更新为

componentWillReceiveProps(nextProps) {
    this.setState({
        loaded: nextProps.posts && nextProps.posts.length
    });
}

这将设置本地状态,最初将显示spinner/loader,然后显示postsno posts。但是,据我所知,React文档不鼓励setState中的componentWillReceiveProps,因为lifecycle钩子在React 16中会被多次调用,并且也已弃用。

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

  1. 仅在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>
            );
        }
    }
    

这里所有内容仅在Redux存储中维护。如果有其他更好的方法,那么我很想知道。谢谢!

2 个答案:

答案 0 :(得分:4)

推荐的解决方案是将其移动到mapStateToProps。大多数情况下,当您需要从商店中获取数据(此处为posts)或从商店中获取数据(此处为loading)时,mapStateToProps是注入数据的正确位置。通常最好使组件保持沉默,以免从存储中获取数据。同样,将状态保持在从商店派生的组件中也违反了单一的真理原则,因为如果您不注意,状态可能会不同步:

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);

答案 1 :(得分:3)

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