将值从组件传递到Redux存储

时间:2019-12-22 15:10:17

标签: reactjs react-redux

我有一个带有多个投票的投票按钮,当我单击投票按钮时,我看到一个+/-,但没有正确的投票数。我将数字硬编码为12,可以投票赞成或反对。

尽管我不知道如何用计数的真实API值动态填充按钮。

以下是组件中api调用中的正确值:count={api.voteScore} 还要注意减速器/动作SET_VOTE_COUNT

代码如下:

API fetch.js

import React, {Component} from 'react';
import AddButton from './AddButton'

class Posts extends Component {
constructor(props) {
    super(props);

    this.state = {
        response: ''
    };
}

componentDidMount() {
    getPostAsync('/posts').then(data => this.setState({ response: data }));
}

render() {

    return (
    <div className="App">
        <header className="App-header">
        <img src={logo} className="App-logo" alt="logo" />

        {Array.isArray(this.state.response) &&
            this.state.response.map(api => <>

                { api.voteScore}
                {console.log(api.voteScore)}

                <AddButton className="voting"
                    count={api.voteScore} />
                <p> { api.title }, by { api.author } </p>
                <p> { api.body } </p>
                <p> {api.category} </p>
            </>
        )}

        </header>
    </div>
    )
}
}
async function getPostAsync(api) {
    let response = await fetch(api);
    let data = await response.json()
    return data;
}

export default Posts;

AddButton.js

import React from 'react';
import { connect } from 'react-redux';

const mapDispatchToProps = dispatch => {
  return {
    // dispatching plain actions
    setVoteCount: () => dispatch({ type: 'SET_VOTE_COUNT', count: '12' }),
  }
}

const AddButton = props => (
  <div className="voting">
    <button onClick={() => {
      console.log(props.setVoteCount(props.count));
    }}>
      Vote
    </button>
  </div>
);


export default connect(null, mapDispatchToProps)(AddButton);

action.js

export const setVoteCount = (id) => {
    return {
        type: "SET_VOTE_COUNT",
        count: '',
        id
    };
}

reducer.js

import { createStore, applyMiddleware, compose } from 'redux';
const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose;

const change_counter = (state = {}, action) => {
    switch (action.type) {

        case "SET_VOTE_COUNT":
        if (state.id !== action.id) {
            return state;
        }
        return {
                ...state,
        }
        case "INCREMENT":
        if (state.id !== action.id) {
            return state;
        }
        return {
            ...state,
            count: parseInt(state.count) + 1
        };
        case "DECREMENT":
        if (state.id !== action.id) {
            return state;
        }

        return {
            ...state,
            count: parseInt(state.count) - 1
        };
        default:
        return state;
    }
    };
    let nextId = 0;
    const counters = (state = [], action) => {
        switch (action.type) {
        case "ADD_COUNTER":
            return [...state, {id: nextId++, count: 0}];
        case "SET_VOTE_COUNT":
                return [...state, {id: nextId++, count: action.count}];
        case "INCREMENT":
            return state.map(counter => change_counter(counter, action));
        case "DECREMENT":
            return state.map(counter => change_counter(counter, action));
        default:
            return state;
        }
    }
    export default createStore(counters, composeEnhancers(applyMiddleware()));

预先感谢

1 个答案:

答案 0 :(得分:1)

使用react-redux的useSelector从功能组件内部的存储中获取值。您也可以使用useDispatch代替connect

我还建议添加redux-thunk以便创建异步操作。

actions.js

async function getPostAsync(api) {
    let response = await fetch(api);
    let data = await response.json()
    return data;
}

export const setVoteCount = (id) => {
    return {
        type: "SET_VOTE_COUNT",
        count: '',
        id
    };
}

export const fetchVoteCount = () => {
  return function (dispatch) {
    getPostAsync('/posts').then(data => {
      dispatch(setVoteCount(data));
    }));
  };
}

AddButton.js

import { useDispatch, useSelector } from 'react-redux';
import React from 'react';


export default function AddButton(props) {
  const dispatch = useDispatch();
  const voteCount = useSelector(state => state.count);

  return (
    <div className="voting">
      <button onClick={() => {
        dispatch({ type: 'SET_VOTE_COUNT', count: voteCount + 1 })
      }}>
        Vote
      </button>
    </div>
  );
}