2017-09-12 3 views
1

Ich fand ein Problem, das wirklich Kopfschmerzen verursachen, ich arbeite derzeit mit reagieren Dan Redux für eine CRUD UI.React-Redux Zustand und Requisiten aktualisiert, aber Komponente nicht neu rendern

alles funktioniert gut, bis ich fand meine "Seite bearbeiten" funktioniert nicht ordnungsgemäß, ich fand heraus, dass, nachdem ich meinen globalen Zustand von Reducer auf lokale Komponenten Requisiten, offensichtlich die Komponente nicht aktualisiert oder neu zu rendern alle. Hier ist das Beispiel meiner 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}) 
     }) 
    } 
} 

und schließlich 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> 
     ); 
    } 
} 

hier ist das, was wie ist aussehen, wenn ich es in Browser ausgeführt:

enter image description here

Werte in Text Box ist der Wert des vorherigen Status, obwohl der Status aktualisiert wird, aber die Komponente erst wieder reriert Ich aktualisiere die Seite.

also kann mir bitte jemand helfen? Bitte helfen Sie mir freundlicherweise ..

Grüßen,

Vidy Hermes

+0

Könnten Sie bitte etwas Code Probe schicken?Nur durch das Betrachten von Screenshots wird es ein bisschen schwierig, Ihnen zu helfen :) Versuchen Sie auch, 'console.log' Sie in Ihrer Komponente anzugeben. Geben Sie – mersocarlin

+0

den Reducer-Code ein, der den neuen Status – Karim

+0

produzieren soll. Lassen Sie uns außerdem wissen, ob Sie eine Komponente oder PureComponent verwenden. PureComponents shallow compare erkennt Prop-Änderungen an einem Objekt nicht, wenn nur untergeordnete Werte geändert werden. –

Antwort

1

Entfernen Sie einfach die defaultValue von Ihren Eingangskomponenten. defaultValue verwandelt sie in unkontrollierte Komponenten.

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

Wenn Sie Ihre Komponentenwerte aktualisieren möchten:

<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

Warum bin ich so dumm, und vielen Dank, ich habe ähnliches Problem vor ... hier ist https://stackoverflow.com/questions/42807901/react-input-element-value-vs-default -Wert .... – vidihermes

+0

aber haben Sie irgendeine Lösung für mich, wenn ich nicht eine Funktion innerhalb OnChange Ereignis aufrufen, Textfelder werden nur gelesen, aber ich brauche wirklich keine Funktion aufrufen, da ich nicht ' t müssen Sie den Zustand der Komponenten ändern, danke – vidihermes

0

Ich bin nicht sicher, ob dies der Fall ist, aber ich sehe zwei Dinge, die relevant sein können (es ist zu lang für einen Kommentar, so dass, wenn es ist nicht die Lösung, die ich diese Antwort werde bearbeiten/löschen):
in Ihrem Minderer, anstelle das Statusobjekt mutierender versuchen, gerade ein neues Objekt zurück auf jeden case Block:

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;  
    } 
} 

eine andere Sache, ther e ist keine Notwendigkeit, diese Zeile Code in Ihre constructor schreiben:
this.state Ich bin fast sicher, es ist nicht mit Ihrem Problem verbunden, aber das sollte nicht da sein, wenn Sie nicht die state;

+0

Ich versuche gerade, den Zustand in meinem Reduzierer direkt zurückzugeben und auch this.state in Compnents Konstruktor zu entfernen, aber nichts hat sich geändert, Komponente wird immer noch nicht aktualisiert. Aber danke – vidihermes

Verwandte Themen