2017-07-11 81 views
0

我正在努力使用反應路由器REDX和一切都很好,除了道具改變渲染。反應路由器還沒有渲染道具改變

Index.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, 
    } 
} 
+0

什麼成分,當你正在更新什麼道具是不是重新渲染? –

+0

@JacobPålssonclass'SignPaze1' in signpaze1.js文件不會再渲染'(我的意思是,第一次加載頁面時,'SignPaze1'呈現良好,但道具改變後,它不會)。我在'mapStateToProps()'中找到'console.log'運行良好,但在'SignPaze1'類的成員函數'render()'中沒有找到。 – HyeonJunOh

+0

你可以顯示你的action.js文件 –

回答

2

我相信這裏的問題是,你應該使用combineReducers,而不是包含嵌套對象的單減速。

您可能需要專門爲signData創建一個reducer,並使用Redux的combineReducers方法。

新文件:signDataReducer.js

​​

reducer.js

import { combineReducers } from 'redux'; 
import signDataReducer from './signDataReducer'; 

export default combineReducers({ 
    signDataReducer 
}); 

這是以前沒有工作是因爲其原因如何Object.assign的作品,它複製的signData參考分配給創建的新對象。

然後,當SignPaze1道具通過淺比較進行比較時,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 
+0

它適合我!感謝幫助:) – HyeonJunOh