2017-09-12 151 views
1

我發現了一個真正令我頭痛的問題,我目前正在使用CRUD UI進行反應。React-redux狀態和道具已更新,但組件不在重新渲染

一切工作正常,直到我發現我的「編輯頁面」無法正常工作,我發現後,我從減速機映射到本地組件的道具,顯然該組件不更新或重新呈現在所有。這裏是我的JavaScript的例子:

index.js:

import React from "react"; 
import ReactDOM from "react-dom"; 
import {Router, Route, IndexRoute, hashHistory} from "react-router"; 
import {Provider} from "react-redux"; 
import store from "./store/store"; 

import Department from "./components/pages/department/index"; 
import DepartmentAdd from "./components/pages/department/add"; 
import DepartmentEdit from "./components/pages/department/edit"; 

const app = document.getElementById("app"); 
ReactDOM.render(
    <Provider store={store}> 
     <Router history={hashHistory}> 

      <Route path="/" component={Layout} onEnter={requireLogin}> 
       <IndexRoute component={Dashboard} onEnter={requireLogin}/> 
       <Route path="error404" component={ERROR404}/> 

       <Route path="department" onEnter={requireLogin}> 
        <IndexRoute component={Department}/> 
        <Route path="add" component={DepartmentAdd}/> 
        <Route path="edit/:id" component={DepartmentEdit}/> 
       </Route> 
      </Route> 
     </Router> 
    </Provider> 
    , app); 

departmentReducer.js

export default function (state = { 
    message: null, 
    activeRow: {}, 
    error: false 

}, action) { 

    switch (action.type) { 

     case "GET_SINGLE_DEPARTMENT": { 
      state = { 
       ...state, 
       activeRow: {...action.payload.data}, 
       message: action.payload.success.message, 
       error: false 
      }; 
      break; 
     } 

     case "GET_SINGLE_DEPARTMENT_FAILED": { 
      state = {...state, message: action.payload.error.message, error: true}; 
      break; 
     } 
     default: { 
      state = {...state}; 
      break; 
     } 

    } 
    return state; 
} 

store.js

import {createStore, applyMiddleware} from "redux"; 
import thunk from "redux-thunk"; 
import {createLogger} from "redux-logger"; 
import promise from "redux-promise-middleware"; 
import {composeWithDevTools} from "redux-devtools-extension"; 
import persistState from 'redux-localstorage'; 

import combineReducer from "./../reducers/combineReducer"; 

const middleware = composeWithDevTools(applyMiddleware(promise(), thunk, createLogger()), persistState()); 

export default createStore(combineReducer, middleware); 

combineReducer.js

import {combineReducers} from "redux"; 
import departmentReducer from "./departmentReducer"; 

export default combineReducers({ 
    departmentReducer 
}); 

departmentActions.js

import axios from "axios"; 

export function getSingleDepartment(id = 0) { 
    return function (dispatch) { 
     axios.get('department/show/' + id).then((response) => { 
      dispatch({type: "GET_SINGLE_DEPARTMENT", payload: response.data}) 
     }).catch((error) => { 
      dispatch({type: "GET_SINGLE_DEPARTMENT_FAILED", payload: error.response.data}) 
     }) 
    } 
} 

最後edit.js

import React from "react"; 
import ContentHeader from "./../shared/ContentHeader"; 
import {connect} from "react-redux"; 
import {hashHistory} from "react-router"; 
import {getSingleDepartment} from "./../../../actions/departmentActions"; 
import ErrorAlert from "./../shared/ErrorAlert"; 
import SuccessAlert from "./../shared/SuccessAlert"; 

@connect((store) => { 
    return { 
     activeRow: store.departmentReducer.activeRow, 
     error: store.departmentReducer.error, 
     message: store.departmentReducer.error, 
    } 
}) 

export default class index extends React.Component { 

    constructor() { 
     super(); 
     this.state 
    } 

    componentDidMount() { 
     this.props.dispatch(getSingleDepartment(this.props.params.id)); 
    } 

    render() { 
     const {namaDepartment, deskripsiDepartment} = this.props.activeRow; 
     return (
      <section> 
       <ContentHeader title="Edit Department"/> 
       <div class="body"> 
        <div class="bodyWrapper col-lg-12 col-md-12 col-sm-12 col-xs-12"> 
         <ErrorAlert error={this.props.error} message={this.props.message}/> 
         <SuccessAlert error={this.props.error} message={this.props.message}/> 
         <form onSubmit={this.saveProfile.bind(this)}> 
          <div className="half col-lg-6 col-md-6 col-sm-12 col-xs-12"> 
           <div className="feWrapper"> 
            <label for="nama">Nama Department</label> 
            <input defaultValue={namaDepartment} 
              type="text" 
              ref="nama" 
              id="nama" 
              name="nama" 
              className="form-control"/> 
           </div> 
           <div className="feWrapper"> 
            <label for="nama">Deskripsi Department</label> 
            <textarea defaultValue={deskripsiDepartment} 
              type="text" 
              ref="deskripsi" 
              id="deskripsi" 
              name="deskripsi" 
              className="form-control"/> 
           </div> 
           <div className="feWrapper"> 
            <ul className="myBtnGroup"> 
             <li> 
              <input onClick={this.onReturnToMain.bind(this)} type="button" 
                value="kembali" 
                className="btn btn-info"/> 
             </li> 
             <li> 
              <input onClick={this.cancelSave.bind(this)} type="button" value="batal" 
                className="btn btn-primary"/> 
             </li> 
             <li> 
              <input type="submit" value="ubah" className="btn btn-info"/> 
             </li> 
            </ul> 
           </div> 
          </div> 
          <div className="clearfix"></div> 
         </form> 
        </div> 
        <div class="clearBoth"></div> 
       </div> 
      </section> 
     ); 
    } 
} 

這裏是什麼,是看當我在瀏覽器中運行,如:內文

enter image description here

值框是先前狀態的值,雖然狀態正在更新,但組件不會重新渲染直到我刷新頁面。

所以請任何人都可以幫我嗎?請您幫助我..

問候,

Vidy愛馬仕

+0

能否請您發送一些示例代碼?僅僅通過查看屏幕截圖有點難以幫助你:)另外,嘗試在組件中聲明「console.log」。 – mersocarlin

+0

發佈應產生新狀態的減速器代碼 – Karim

+0

另外,讓我們知道您是使用Component還是PureComponent。如果僅更改了子值,PureComponents淺層比較將無法檢測對象上的支柱更改。 –

回答

1

只需從輸入組件中刪除defaultValue即可。 defaultValue將它們變成不受控制的組件。

https://facebook.github.io/react/docs/uncontrolled-components.html#default-values

如果要更新組件值:

<input 
    type="text" 
    ref="nama" 
    id="nama" 
    name="nama" 
    className="form-control" 
    value={namaDepartment} 
/> 

<textarea 
    type="text" 
    ref="deskripsi" 
    id="deskripsi" 
    name="deskripsi" 
    className="form-control" 
    value={deskripsiDepartment} 
/> 
+0

爲什麼我這麼愚蠢,非常感謝你,我遇到過類似的問題......這裏是https://stackoverflow.com/questions/42807901/react-input-element-value-vs-default - 值.... – vidihermes

+0

但你有我的任何解決方案,如果我不調用一個函數內onChange事件,文本框變成只讀,但我真的不需要調用任何函數,因爲我不' t需要更改任何組件狀態,謝謝 – vidihermes

0

我不知道這樣的話,但我看到兩件事情,可能是相關的(它太長了評論,所以如果這不是解決辦法,我會編輯/刪除這個答案):
你的機內部,而不是突變的狀態對象嘗試只是返回每個case塊上一個新的對象:

export default function (state = { 
    message: null, 
    activeRow: {}, 
    error: false 

}, action) { 

    switch (action.type) { 

     case "GET_SINGLE_DEPARTMENT": { 
      return { 
       ...state, 
       activeRow: {...action.payload.data}, 
       message: action.payload.success.message, 
       error: false 
      }; 
     } 

     case "GET_SINGLE_DEPARTMENT_FAILED": { 
      return {...state, message: action.payload.error.message, error: true}; 
     } 
     default: 
      return state;  
    } 
} 

另一件事,療法e是沒有必要寫在你的constructor這個代碼行:
this.state我幾乎可以肯定它與你的問題沒有關係,但如果你不填充state;

+0

我只是試圖直接返回我的reducer中的狀態,並且還刪除了compnent的構造函數中的this.state,但沒有任何更改,組件仍然不會更新。但是,謝謝 – vidihermes

相關問題