2017-09-12 91 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

相关问题