我是 React + Redux 新手。我遇到了一个问题,当我调度操作时,我的应用程序不会重新渲染。但是,我使用 getState() 检查状态,它确实发生了变化。我查阅了文档,但仍然不知道问题出在哪里。请帮助我,谢谢。
代码如下
====actions.js====
export const ADD_MAIL = 'ADD_MAIL';
export const DEL_MAIL = 'DEL_MAIL';
export function addMail(email) {
return {
type: ADD_MAIL,
email
}
}
export function delMail(id) {
return {
type: DEL_MAIL,
id
}
}
====reducers.js====
import { combineReducers } from 'redux'
import { ADD_MAIL, DEL_MAIL } from '../actions/actions'
import MAILS from '../data'
function emails(state = MAILS, action) {
switch (action.type) {
case ADD_MAIL:
console.log("ADD_MAIL");
return [
action.email,
...state
];
case DEL_MAIL:
let idx = state.length;
let i = 0;
// Find the target mail
while(idx--) {
if (state[idx] && state[idx].serialNo === action.id)
i = idx;
}
let arr1 = state.slice(0, i);
let arr2 = state.slice(i + 1);
let newList = arr1.concat(arr2);
console.log("DEL_MAIL");
return newList;
default:
return state;
}
}
const rootReducer = combineReducers({
emails
});
export default rootReducer;
====main.js====
import React from 'react'
import { render } from 'react-dom'
import { Link } from 'react-router'
import { connect } from 'react-redux'
import { createStore } from 'redux'
import { addMail, delMail } from './actions/actions'
import rootReducer from './reducers/reducers'
import * as btn from './module/button'
import * as module from './module/module'
var store = createStore(rootReducer);
class Inbox extends React.Component {
constructor(props) {
super(props);
this.state = {
searchText: ''
}
this.handleUserInput = this.handleUserInput.bind(this);
this.deleteMail = this.deleteMail.bind(this);
this.sendMail = this.sendMail.bind(this);
}
handleUserInput(searchText) {
this.setState({
searchText: searchText
});
}
deleteMail(obj) {
store.dispatch(delMail(obj.serialNo));
console.log(store.getState());
// This displays the correct new state in console after dispatch
}
sendMail(newMail) {
store.dispatch(addMail(newMail));
console.log(store.getState());
// This displays the correct new state in console after dispatch
}
render() {
let mails = [];
let search = this.state.searchText.toUpperCase();
let emails = this.props.emails;
emails.map(mail => {
if (mail.from.toUpperCase().indexOf(search) !== -1)
mails.push(mail);
});
let sender = (mails.length === emails.length) ? "all" : this.state.searchText;
return (
<div className="main">
<div className="toolbar">
<span>You have {mails.length} message from {sender}.</span>
<module.SearchInput searchText={this.state.searchText} onUserInput={this.handleUserInput} />
<div className="functions">
<btn.AddButton />
</div>
</div>
<div className="mailList">
{mails.map(mail => (
<div className="item" key={mail.serialNo}>
<div className="info sender">
From: {mail.from}
</div>
<div className="info date">
{mail.date}
</div>
<div className="info subject">
Subject: {mail.subject}
</div>
<div className="functions">
<btn.ReadButton serialNo={mail.serialNo} />
<btn.DeleteButton serialNo={mail.serialNo} deleteMail={this.deleteMail} />
</div>
</div>
))}
</div>
<module.NewMailInput sendMail={this.sendMail} />
</div>
);
}
}
function mapStateToProps(state) {
return {
emails: state.emails
};
}
export default connect(mapStateToProps)(Inbox);
====app.js====
import React from 'react'
import { render } from 'react-dom'
import { Router, Route, IndexRoute, browserHistory } from 'react-router'
import { createStore } from 'redux'
import { Provider } from 'react-redux'
import { Menu } from './menu'
import { Mail } from './main'
import Inbox from './main'
import rootReducer from './reducers/reducers'
var store = createStore(rootReducer);
class App extends React.Component {
constructor(props) {
super(props);
}
render() {
return (
<div style={{height: '100%'}}>
<Menu />
{this.props.children}
</div>
);
}
}
class Home extends React.Component {
constructor(props) {
super(props);
}
render() {
return (
<Inbox />
);
}
}
render(
<Provider store={store}>
<Router history={browserHistory}>
<Route path="/" component={App}>
<IndexRoute component={Home} />
<Route path="/inbox" component={Inbox} />
<Route path="/message/:mailSerial" component={Mail} />
</Route>
</Router>
</Provider>,
document.getElementById('app-container'))
最佳答案
试试这个:
import React from 'react'
import { render } from 'react-dom'
import { Link } from 'react-router'
import { connect } from 'react-redux'
import { addMail, delMail } from './actions/actions'
import * as btn from './module/button'
import * as module from './module/module'
class Inbox extends React.Component {
constructor(props) {
super(props);
this.state = {
searchText: ''
}
this.handleUserInput = this.handleUserInput.bind(this);
this.deleteMail = this.deleteMail.bind(this);
this.sendMail = this.sendMail.bind(this);
}
handleUserInput(searchText) {
this.setState({
searchText: searchText
});
}
deleteMail(obj) {
this.props.delMail(obj.serialNo); //Call the delMail action
console.log(store.getState());
}
sendMail(newMail) {
this.props.addMail(newMail); //Call the addMail action
console.log(store.getState());
}
render() {
let mails = [];
let search = this.state.searchText.toUpperCase();
let emails = this.props.emails;
emails.map(mail => {
if (mail.from.toUpperCase().indexOf(search) !== -1)
mails.push(mail);
});
let sender = (mails.length === emails.length) ? "all" : this.state.searchText;
return (
<div className="main">
<div className="toolbar">
<span>You have {mails.length} message from {sender}.</span>
<module.SearchInput searchText={this.state.searchText} onUserInput={this.handleUserInput} />
<div className="functions">
<btn.AddButton />
</div>
</div>
<div className="mailList">
{
mails.map(mail => (
<div className="item" key={mail.serialNo}>
<div className="info sender">From: {mail.from}</div>
<div className="info date">{mail.date}</div>
<div className="info subject">Subject: {mail.subject}</div>
<div className="functions">
<btn.ReadButton serialNo={mail.serialNo} />
<btn.DeleteButton serialNo={mail.serialNo} deleteMail={this.deleteMail} />
</div>
</div>
))
}
</div>
<module.NewMailInput sendMail={this.sendMail} />
</div>
);
}
}
function mapStateToProps(state) {
return {
emails: state.emails
};
}
//Connect the component to re-render when state change and
// makes the emails and actions to be available through this.props
export default connect(mapStateToProps, {delMail, addMail})(Inbox);
//To connect Mail component which I suppose that is in another file
function mapStateToProps(state) {
return { emails: state.emails };
}
export default connect(mapStateToProps, {})(Mail);
关于javascript - Redux - 应用程序在分派(dispatch)后不会重新渲染,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40507186/