我是新来反应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。相反,将理解适当的解决方案。谢谢。
答案 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;
}
};