我正在努力使用 react router redux,一切都很好,除了在 props 更改时渲染。
索引.js
import React from 'react';
import ReactDOM from 'react-dom';
import {Provider} from 'react-redux';
import {createStore, combineReducers, applyMiddleware} from 'redux';
import {Router, Route, browserHistory} from 'react-router';
import { syncHistoryWithStore, routerReducer, routerMiddleware } from 'react-router-redux';
import App from './app';
import Sign from '../sign/app';
import SignInfo from '../sign/redux/reducer';
let store = createStore(
combineReducers({
SignInfo,
routing: routerReducer
}),
);
const history = syncHistoryWithStore(browserHistory, store);
class Index extends React.Component {
constructor(props) {
super(props);
}
render() {
console.log('root')
return (
<Provider store={store}>
<Router history={history}>
<Route path="/" component={App}/>
<Route path="/sign" component={Sign}/>
</Router>
</Provider>
);
}
}
ReactDOM.render(<Index/>, document.getElementById('root'));
sign.js
import React from 'react';
import {connect} from 'react-redux';
import Belle from 'belle';
import {Grid, Row, Col} from 'react-flexbox-grid';
import { withRouter } from 'react-router';
import SignPaze1 from './signPaze1'
class App extends React.Component {
constructor(props) {
super(props);
}
render() {
const mainCardStyle = {
border: '1px solid #aaa',
}
return (
<div className="sign-page">
<SignPaze1/>
</div>
)
}
}
function mapStateToProps(state) {
return {
}
}
export default withRouter(connect(mapStateToProps)(App));
signPaze1.js
import React from 'react';
import { bindActionCreators } from 'redux';
import {connect} from 'react-redux';
import Belle from 'belle';
import { withRouter } from 'react-router';
import {Grid, Row, Col} from 'react-flexbox-grid';
import {handleSignInput} from './redux/action';
class SignPaze1 extends React.Component {
constructor(props) {
super(props);
this.handleInputValue = this.handleInputValue.bind(this);
}
handleInputValue(e) {
let {dispatch} = this.props;
console.log('on render')
const action = bindActionCreators(handleSignInput, dispatch)
action(e.target.id, e.target.value);
}
render() {
let signData = this.props.signData;
let mainCardStyle = {
border: '1px solid #aaa',
}
return (
<Grid>
<Row>
<Col xs={12}>
<Belle.Card style={mainCardStyle}>
<Row center="md">
<Col xs={12} sm={6} md={4} lg={3}
className="input-group">
<input type="text"
id="company_number"
value={signData.company_number}
onChange={this.handleInputValue}/>
</Col>
<Col xs={12} sm={6} md={4} lg={3}
mdOffset={1} lgOffset={2}
className="input-group">
<Belle.TextInput
onUpdate={this.handleInputValue.bind(this, 'data')}/>
</Col>
</Row>
<Row center="md">
<Col xs={12} sm={6} md={4} lg={3}
className="input-group">
<Belle.TextInput
onUpdate={this.handleInputValue.bind(this, 'da2')}/>
</Col>
<Col xs={12} sm={6} md={4} lg={3}
mdOffset={1} lgOffset={2}
className="input-group">
<Belle.TextInput
onUpdate={this.handleInputValue.bind(this, 'dat3')}/>
</Col>
</Row>
</Belle.Card>
</Col>
</Row>
</Grid>
)
}
}
function mapStateToProps(state) {
console.log(state.SignInfo);
return {
signData: state.SignInfo.signData,
}
}
export default withRouter(connect(mapStateToProps)(SignPaze1));
reducer.js
import {HANDLE_SIGN_INPUT} from './action';
const initialMainState = {
signData: {
company_number: 'asdas|',
company_name: '',
username: '',
email: '',
email_confirm: '',
password: '',
password_confirm: '',
}
}
function SignInfo(state = initialMainState, action) {
let newVal = {};
switch (action.type) {
case HANDLE_SIGN_INPUT:
newVal = Object.assign({}, state);
newVal.signData[action.target] = action.value;
return newVal;
default:
return state;
}
}
export default SignInfo;
有人说在导出行上添加 withRouter
函数可以修复这个错误,但事实并非如此。 (here)。但是,当 SignPaze1
的成员状态发生更改时,通常会再次呈现。
我该如何解决这个由 react-router-redux 引起的问题?
编辑
Action .js
export const HANDLE_SIGN_INPUT = 'HANDLE_SIGN_INPUT';
export function handleSignInput(target, value){
return {
type: HANDLE_SIGN_INPUT,
target: target,
value: value,
}
}
最佳答案
我认为这里的问题是您应该使用 combineReducers
,而不是包含嵌套对象的单个 reducer。
您可能需要专门为 signData
创建一个 reducer,并使用 Redux 的 combineReducers
方法。
新文件:signDataReducer.js
import {HANDLE_SIGN_INPUT} from './action';
const initialMainState = {
company_number: 'asdas|',
company_name: '',
username: '',
email: '',
email_confirm: '',
password: '',
password_confirm: '',
};
export default function SignData (state = initialMainState, action) {
let newVal = {};
switch (action.type) {
case HANDLE_SIGN_INPUT:
newVal = Object.assign({}, state);
newVal[action.target] = action.value;
return newVal;
default:
return state;
}
}
reducer.js
import { combineReducers } from 'redux';
import signDataReducer from './signDataReducer';
export default combineReducers({
signDataReducer
});
它之前不工作的原因是 Object.assign
的工作方式,它将 signData
的 reference 复制到新的分配创建的对象。
然后当 SignPaze1
Prop 通过浅比较进行比较时,signData
是与之前完全相同的对象,因此被认为是相等的。并且没有渲染发生。
即
const initialMainState = {
signData: {
company_number: 'asdas|',
company_name: '',
username: '',
email: '',
email_confirm: '',
password: '',
password_confirm: '',
}
}
const newState = Object.assign({}, initialMainState);
newState.signData.company_name = 'Hello!';
// => "Hello!"
initialMainState.signData.company_name
// => "Hello!"
newState.signData === initialMainState.signData
// => true
关于javascript - react router redux 不会在 props 更改时呈现,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45032934/