更新值并将它们保存在 Redux 中

Updating values and saving them in Redux

我对 redux 还很陌生,但仍在尝试着去尝试它。我正在开发一个从端点获取数据并呈现项目的迷你应用程序。然后用户可以 "pin" 这些项目,这是我不确定的部分。

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

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

我的reducer具备处理这个action的条件

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

我在这里的 objective 是能够通过单击图标固定 post,然后在 "Pinned" 部分下显示 post 而不是比 "Posts" 部分。

this.props.posts 数组由默认情况下具有 pinned: false 的 属性 的对象以及与其关联的其他属性组成。如果固定,我希望将其设置为 'true',如果未固定,则重置为 'false'。

我该怎么做?我需要采取其他措施来处理这个问题吗?

想法是,首先你需要在固定按钮的 redux store onClick 中更新特定 post 的固定 属性。为此,您需要将唯一的 属性 (post id) 与 onClick 方法绑定,并使用该 id 发送一个动作。

步骤:

1-将每个post的唯一id传递给pinPost方法:

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

2- 调度更新 redux 存储中 post 的 pinned 属性 的操作:

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

3- 定义 updatePost 为:

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

4- 现在在 reducer 中更新那个 post:

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