更改状态时组件无法重新呈现

时间:2016-09-19 13:26:12

标签: javascript reactjs redux react-redux

我是新手做出反应。我想确认输入JSON是否有效并在scree上显示。正在触发ValidConfiguration操作,reducer返回新状态,但智能组件add-config-container未被重新呈现

以下是我的文件: 操作

import {
    VALID_CONFIGURATION,
    INVALID_CONFIGURATION,
    SAVE_CONFIGURATION,
    START_FETCHING_CONFIGS,
    FINISH_FETCHING_CONFIGS,
    EDIT_CONFIGURAION
} from '../constants';

function validateConfiguration(jsonString) {
    try {
        JSON.parse(jsonString);
    } catch (e) {
        return false;
    }
    return true;
}

export function isConfigurationValid(state) {
    if (validateConfiguration(state.jsonText)) {
        return({type: VALID_CONFIGURATION, state : state});
    } else {
        return({type: INVALID_CONFIGURATION, state : state});
    }
}

export function fetchConfiguration() {
    return ({type : START_FETCHING_CONFIGS});
}

export function finishConfiguration(configs) {
    return ({type : FINISH_FETCHING_CONFIGS, configs: configs});
}

export function editConfiguration(index) {
    return ({type : EDIT_CONFIGURATION, index : index});
}

export function saveConfiguration(config) {
    return ({type: SAVE_CONFIGURATION, config : config});
}

容器组件

import React, {Component} from 'react';
import {Button, Input, Snackbar} from 'react-toolbox';
import {isConfigurationValid, saveConfiguration} from '../../actions/config';
import { connect } from 'react-redux';
import style from '../../theme/layout.scss';

class AddConfigContainer extends Component {

    constructor(props) {
        super(props);
        this.state = {jsonText: '', key: '', valid: false, showBar : true};
    }

    handleChange(text, value) {
        this.setState({[text]: value});
    }

    handleSnackbarClick() {
        this.setState({ showBar: false});
    };

    handleSnackbarTimeout() {
        this.setState({ showBar: false});
    };

    render() {
        let {onValid} = this.props;
        return (
            <div>
                <h4>Add Configs</h4>
                <span>Add configs in text box and save</span>

                <Input type='text' label='Enter Key'
                       value={this.state.key} onChange={this.handleChange.bind(this, 'key')} required/>

                <Input type='text' multiline label='Enter JSON configuration'
                       value={this.state.jsonText} onChange={this.handleChange.bind(this, 'jsonText')} required/>

                <div>IsJSONValid = {this.state.valid ? 'true': 'false'}</div>

                <Snackbar action='Dismiss'
                          label='JSON is invalid'
                          icon='flag'
                          timeout={2000}
                          active={ this.state.showBar }
                          onClick={this.handleSnackbarClick.bind(this)}
                          onTimeout={this.handleSnackbarTimeout.bind(this)}
                          type='accept'
                          class = {style.loader}
                />

                <Button type="button" label = "Save Configuration" icon="add" onClick={() => {onValid(this.state)}}
                        accent
                        raised/>
            </div>
        );
    }
}

const mapStateToProps = (state) => {
    let {
        jsonText,
        key,
        valid
    } = state;

    return {
        jsonText,
        key,
        valid
    };
};

const mapDispatchToProps = (dispatch) => {
    return {
        onValid : (value) => dispatch(isConfigurationValid(value)),
        saveConfiguration: (config) => dispatch(saveConfiguration(config))
    }
};

export default connect(mapStateToProps, mapDispatchToProps)(AddConfigContainer);

减速

import assign from 'object.assign';
import {VALID_CONFIGURATION, INVALID_CONFIGURATION} from '../constants';

const initialState = {
    jsonText : '',
    key : '',
    valid : false,
    showBar: false,
    configs: [json],
    activeConfig : {},
    isFetching: false
};

export default function reducer(state = initialState, action) {
    if (action.type === VALID_CONFIGURATION) {
        return (assign({}, state, action.state, {valid: true}));
    } else if (action.type === INVALID_CONFIGURATION) {
        return assign({}, state, action.state, {valid: false});
    } else {
        return state;
    }
}

1 个答案:

答案 0 :(得分:1)

我认为您的组件会重新渲染,但您实际上从未使用道具中的valid值(即this.props.valid)。您只使用this.state.valid,但在代码中的任何位置都不会更改。请注意,Redux不会(并且无法)更改组件的内部状态,它只会将新的道具传递给组件,因此您需要使用this.props.valid来查看更改发生的情况。从本质上讲,您应该考虑是否需要valid存在于组件的状态中。我不认为你这样做,在这种情况下你所拥有的所有数据(除了showBar除外)都不需要在那里,你可以从道具中取出它。

如果由于某种原因确实需要让它们处于状态,您可以覆盖,例如componentWillReceiveProps更新组件的状态以反映新的道具。