我有这段代码
import React from 'react';
import 'materialize-css/sass/materialize.scss';
import 'materialize-css/js/materialize.js';
import 'font-awesome/scss/font-awesome.scss';
import '../styles/main.scss';
export default class AddStorageModal extends React.Component {
constructor() {
super();
this.state = { storageName: "", sharingKey: "" };
}
handleChange(event) {
this.setState({ [event.target.name]: event.target.value });
}
validate() {
if (this.state.storageName === "" && this.state.sharingKey == "") {
console.log("validation error");
return false;
}
this.props.createNewStorage(this.state);
}
resetForm() {
this.setState({ storageName: "", sharingKey: "" })
$(function () {
Materialize.updateTextFields();
});
}
render() {
if (this.props.storages.openAddStorageModal) {
$('#add-new-storage-modal').openModal({ dismissible: false });
}
else {
$('#add-new-storage-modal').closeModal();
this.resetForm( );
}
return (
<div id="add-new-storage-modal" className="modal" >
<div className="modal-content">
<h6>Enter your new Storage (Freezer, Pantry, etc.) </h6>
<div className="row">
<form>
<div className="input-field col s12 m12 l12 ">
<input id="storage_name" type="text" value={this.state.storageName} name="storageName" onChange={ (event) => this.handleChange(event) } />
<label htmlFor="storage_name">Storage Name</label>
</div>
<br />
<h4 className="center">OR</h4>
<h6>Enter in the sharing key you were given.</h6>
<div className="input-field col s12 m12 l12 ">
<input id="sharing_key" type="text" value={this.state.sharingKey} name="sharingKey" onChange={ (event) => this.handleChange(event) } />
<label htmlFor="sharing_key">Sharking Key</label>
</div>
</form>
</div>
</div>
<div className="modal-footer">
<a href="#!" className="waves-effect waves-green btn-flat left" onClick={() => this.validate() }>Add</a>
<a href="#!" className="waves-effect waves-green btn-flat" onClick={() => this.props.loadAddStorageModal(false) }>Cancel</a>
</div>
</div>
)
}
}
我的orignal计划是每次我的模态对话框重新渲染我通过调用resetForm()方法重置表单值。
这不起作用,因为我得到关于&#34;改变状态的错误&#34;在渲染中,现在对我有意义,因为它会导致组件重新渲染。
但是这引出了我的问题,我在哪里清除状态呢?我正在尝试遵循redux模式。
我可以在&#34;验证()&#34;中进行清算。单击添加时的方法。
然而&#34; createNewStorage&#34;做ajax电话。如果ajax调用失败,我不确定如何处理这种情况。作为用户,我希望显示一条错误消息,但模式应该仍然以我输入的值打开。
如果需要,这是完整的代码。
import React from 'react';
import {connect} from 'react-redux';
import {bindActionCreators} from 'redux';
import 'materialize-css/sass/materialize.scss';
import NavigationContainer from './NavigationContainer';
import StorageItemsContainer from './StorageItemsContainer'
import AddStorageModal from './AddStorageModal.js'
import {loadAddStorageModal, createNewStorage} from '../actions/StorageActions.js'
import '../styles/main.scss';
class App extends React.Component {
render() {
return (
<div>
<NavigationContainer />
<div className="container">
<StorageItemsContainer />
</div>
<AddStorageModal {...this.props} />
</div>
)
}
}
function mapStateToProps(state) {
return {
storages: state.storages
};
}
function matchDispatchToProps(dispatch){
return bindActionCreators({loadAddStorageModal: loadAddStorageModal, createNewStorage: createNewStorage}, dispatch);
}
export default connect(mapStateToProps, matchDispatchToProps)(App);
动作
export function fetchStorage() {
return function(dispatch) {
var payload = [
{
id: 1,
name: "Fridge2",
selected: true
},
{
id: 2,
name: "Closet2",
selected: false
},
{
id: 3,
name: "Car2",
selected: false
}
];
dispatch({type: "Fetch_Storage", payload: payload});
}
}
export function loadAddStorageModal(load) {
return function(dispatch) {
dispatch({type: "Load_Add_Storage_Modal", payload: load});
}
}
export function createNewStorage(storage) {
return function(dispatch) {
dispatch({type: "New_Storage_Created", payload: storage});
}
}
export function selectStorage(storageId)
{
return function(dispatch) {
dispatch({type: "Select_Storage", payload: storageId});
}
}
减速
export default function reducer(state = {
fetchedStorages: [],
openAddStorageModal: false,
selectedStorage: null
}, action) {
switch (action.type) {
case "Fetch_Storage": {
var selected;
if(state.fetchedStorages != [])
{
selected = action.payload[0]
}
return {
fetchedStorages: action.payload,
selectedStorage: selected
}
}
case "Load_Add_Storage_Modal": {
return {
openAddStorageModal: action.payload,
fetchedStorages: state.fetchedStorages,
selectedStorage: state.selectedStorage
}
}
case "New_Storage_Created": {
var lastStorage = state.fetchedStorages.slice(-1); // just for now
return {
openAddStorageModal: false,
fetchedStorages: state.fetchedStorages.concat({ id: lastStorage[0].id + 1, name: action.payload.storageName}),
selectedStorage: state.selectedStorage
}
}
case "Select_Storage": {
var existingStorages = state.fetchedStorages;
var selectedStorage = null;
for (var i = 0; i < existingStorages.length; i++) {
var storage = existingStorages[i];
if (action.payload == storage.id) {
storage.selected = true;
selectedStorage = storage;
}else{
storage.selected = false;
}
existingStorages[i] = storage;
}
return {
fetchedStorages: existingStorages,
selectedStorage: selectedStorage
}
}
}
return state;
}
答案 0 :(得分:0)
是的,您只能在生命周期方法和setState
中调用onEvents
。
在您的情况下,因为您依赖道具this.props.storages.openAddStorageModal
您可以在componentWillReceiveProps
生命周期方法中设置您的状态。
将使用nextProps
值调用它,请注意此时未设置道具,您可以将nextProps
参数与之前this.props
中的道具进行比较
将此添加到您的组件,它应该可以正常工作:
componentWillReceiveProps(nextProps) {
if (nextProps.storages.openAddStorageModal) {
$('#add-new-storage-modal').openModal({ dismissible: false });
} else {
$('#add-new-storage-modal').closeModal();
this.resetForm(); // will work fine here..
}
}
答案 1 :(得分:0)
你应该有一个清除状态的动作 - dispatch(props.clearForm)
。
您的商店在收到活动事件时应负责清除其商店状态,从而触发重新呈现。
case CLEAR_FORM:
// return new empty state object
您的表单应该根据商店的状态显示值,因此当重新呈现时,字段应为空。
如果您在每次击键时向商店写新值,则可能需要撤消操作事件,否则您可能会遇到性能问题。