Redux存储更新,但未在组件中呈现

时间:2018-10-05 04:00:45

标签: javascript reactjs redux react-redux single-page-application

我是新来反应js的人。我正在学习redux。在以下示例中,我可以在redux存储中进行更改。但这没有反映在组件中。在这段代码中,我试图通过onClick操作动态添加和删除<BookCard />组件。

这是我的index.js

import React from 'react';
import ReactDOM from 'react-dom';

import { Provider } from 'react-redux';
import { createStore } from 'redux';

import App from './App';

import registerServiceWorker from './registerServiceWorker';
import reducer from './store/reducers/books';

//create store
let store = createStore(reducer); // reducer passed as parameter

const app = (
    <Provider store= { store }>
        <App />
    </Provider>
)

ReactDOM.render(app, document.getElementById('root'));
registerServiceWorker();

App.js:

import React, { Component } from 'react';
import Books from './components/containers/Books';

class App extends Component {

  render() {

    return (
     <Books  />
    );
  }
}

export default App;

Books.js(组件)

import React, { Component } from 'react';
import BookCard from '../presentationals/BookCard';
import { connect } from 'react-redux';
import * as actions from '../../store/actions/books';
import './Books.css';

//Provider/Container React Component
class Books extends Component {

    render() {
    return(
    <div className="books-container">
          { this.props.books.map((book) => 
    <BookCard 
        key = {book}
        cover={ this.props.cover }
        title={ this.props.title }
        author={ this.props.author }
        link={ this.props.link } 
    />
    )
     }
    </div>     
        );
    }
}

const mapStateToProps = state => {
    return {
        cover: state.cover,
        title : state.title,
        author : state.author,
        link : state.link,
        books : state.books
    }
  };


export default connect(mapStateToProps)(Books);

BookCard.js(另一个组件)

import React, { Component} from 'react';
import './BookCard.css';
import { connect } from 'react-redux';
import * as actions from '../../store/actions/index';

class BookCard extends Component {

    addClickHandler = () => {
        this.props.add();
    }

    deleteClickHandler = () => {
        this.props.delete()
    }

    render() {

        return(
            <div>
            <img style={{width: 250, height: 323}} src={this.props.cover} />
            <h2>{this.props.title}</h2>
            <h3>{this.props.author}</h3>
            <a href={this.props.link}>{this.props.link}</a>
            <br/>
            <i className="icon fa fa-pencil" aria-hidden="true"></i>
            <i className="icon fa fa-trash" onClick={ this.deleteClickHandler } aria-hidden="true"></i>
            <i className="icon fa fa-plus" onClick={ this.addClickHandler } aria-hidden="true"></i>
          </div>
        );
    }
}

const mapDispatchToProps = dispatch =>  {
    return {
        add : () => dispatch(actions.addBook()),
        delete :() => dispatch(actions.deleteBook())
    }
}

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

动作文件books.js:

import * as actionTypes from './actionTypes';

export const addBook = () => {
    return {
        type : actionTypes.ADD_BOOK
    }
}

export const deleteBook = () => {
    return {
        type : actionTypes.DELETE_BOOK
    }
}

Reducer文件books.js:

import * as actionTypes from '../actions/actionTypes';

// initial state 
const initialState = {
    books : [0,1,2],
    cover: "https://s3.amazonaws.com/titlepages.leanpub.com/reactjsforthevisuallearner/hero?1496374274",
    title: "React.js for the Visual Learner",
    author: "Mike Mangialardi",
    link: "https://leanpub.com/reactjsforthevisuallearner"
}

const reducer = (state = initialState, action) => {
    switch(action.type) {
        case actionTypes.ADD_BOOK :
            let incremented = Object.assign({}, state);
            incremented.books.push(incremented.books.length);
            return incremented;

        case actionTypes.DELETE_BOOK :
            let decremented = Object.assign({}, state);
            decremented.books.pop();
            return decremented;

        default:
            return state;
    }
}

export default reducer;

actionTypes.js

export const ADD_BOOK = 'ADD_BOOK';
export const DELETE_BOOK = 'DELETE_BOOK';

我尝试使用几种生命周期方法(例如componentWillRecieveProps()componentDidUpdated())来接收更新的道具,但没有一个起作用。

我不想做forceUpdate(),因为它只是一个hack。相反,将理解适当的解决方案。谢谢。

1 个答案:

答案 0 :(得分:1)

我认为问题出在减速器上。然后,尝试以下方法:

const reducer = (state = initialState, action) => {
  switch (action.type) {
    case actionTypes.ADD_BOOK:
      return { ...state, books: state.books.concat(state.books.length) };
    case actionTypes.DELETE_BOOK:
      return { ...state, books: state.books.slice(0, -1) };
    default:
      return state;
  }
};