更新值并将其保存在Redux中

时间:2018-06-19 18:39:01

标签: reactjs redux redux-thunk

我对redux还是很陌生,但仍在努力使自己湿透。我正在开发一个微型应用程序,该应用程序从端点获取数据并呈现项目。然后,用户可以“固定”这些项目,这是我不确定的部分。

在我的操作中,我已经设置了获取数据的逻辑

import {FETCH_POST} from './types';

export function fetchPost() {
    console.log('fetch..');
    return function (dispatch) {
        fetch('https://someapi/.json?count=20')
            .then(res => res.json())
            .then(posts =>
                dispatch({
                    type: FETCH_POST,
                    payload: posts.data.children
                })
            )
        ;
    }
}

我的减速器有条件处理此动作

import {FETCH_POST} from '../actions/types';

const initialState = {
    items: [],
    item: {}
};

export default function(state = initialState, action){
    switch (action.type){
        case FETCH_POST:
            return Object.assign({}, state, {items: action.payload});
        default:
            return state;
    }

}

//Main reducer file

import {combineReducers} from 'redux';
import postReducer from './postReducer';

export default combineReducers({
   post: postReducer
});

这是我的组成部分

class Post extends Component{
    componentWillMount(){
        this.props.fetchPost();
    }

    pinPost(){
       //...not sure how to update here
    }

    render(){
        const postItems = this.props.posts.map(post => (
            <div key={post.data.id} className="listBox">
                <div className="listContent">
                    <i className="fa fa-thumb-tack pin" onClick={this.pinPost}></i>
                    <a href={'https://someapi' + post.data.permalink} target="_blank">{post.data.title}</a>
                </div>
            </div>
        ));

        return(
            <div>
                <h1>Pinned</h1>
                <hr/>
                <h1>Posts</h1>
                {postItems}
            </div>
        );
    }
}

我在这里的目标是能够通过单击图标来固定帖子,然后在“固定”部分而不是“帖子”部分下显示该帖子。

this.props.posts数组由对象组成,这些对象默认具有pinned: false的属性以及与其绑定的其他属性。我希望将其设置为“ true”(如果固定),并重置为“ false”(如果固定)。

我将如何处理?我需要采取其他措施来解决这个问题吗?

1 个答案:

答案 0 :(得分:1)

想法是,首先您需要在redux存储区的onClick固定按钮中更新特定帖子的固定属性。为此,您需要将唯一属性(帖子ID)与onClick方法绑定在一起,并使用该ID调度一个动作。

步骤:

1-将每个帖子的唯一ID传递给pinPost方法:

onClick={this.pinPost.bind(this, post.data.id)}

2-发送操作以更新Redux存储中该帖子的pinned属性:

pinPost(id) {
   this.props.updatePost(id)
}

3-将updatePost定义为:

updatePost(id) {
    dispatch({
        type: 'UPDATE_POST',
        id,
    })
}

4-现在,在reducer中更新该帖子的pinned属性:

export default function(state = initialState, action){
    switch (action.type){
        case FETCH_POST:
            return Object.assign({}, state, {items: action.payload});
        case UPDATE_POST:
            const items = state.items.map(el => el.data.id == action.id ? 
                {data: Object.assign({}, el.data, { pinned: true })} : el
            return Object.assign({}, state, { items })
        default:
            return state;
    }
}

5-现在在不同部分渲染元素:

render(){
    let pinnedPost = [], postItems = []
    this.props.posts.forEach(post => {
        if(post.data.pinned) {
            pinnedPost.push(
                <div key={post.data.id} className="listBox">
                    <div className="listContent">
                        <i className="fa fa-thumb-tack pin"></i>
                        <a href={'https://someapi' + post.data.permalink} target="_blank">{post.data.title}</a>
                    </div>
                </div>
            )
        } else {
            postItems.push(
                <div key={post.data.id} className="listBox">
                    <div className="listContent">
                        <i className="fa fa-thumb-tack pin" onClick={this.pinPost}></i>
                        <a href={'https://someapi' + post.data.permalink} target="_blank">{post.data.title}</a>
                    </div>
                </div>
            )
        }

    ));

    return(
        <div>
            <h1>Pinned</h1>
            {pinnedPost}
            <hr/>
            <h1>Posts</h1>
            {postItems}
        </div>
    );
}