3

React-Redux と Redux を使用している反応アプリに動的な子を挿入しようとしていますが、子の小道具のバインディングで問題が発生しています。問題を次のサンプル コード ( JSFiddle ) にまとめました。問題は、元のレンダリングされた要素は正常に更新されますが、動的に挿入された部分は更新されないことです。奇妙なことは、更新が redux ストアで取得され、小道具に正しく供給されることです。

const initialState = {
  renderProperty: "Red Fish",
  getChildrenProperty: "Blue Fish",
}

function MainReducer(state = initialState, action) {
switch (action.type) {
        case 'PROBLEM_CHILD_INSIDE_RENDER':
            return Object.assign({}, state, {
        renderProperty: action.mutatedProperty
      })
      case 'PROBLEM_CHILD_INSIDE_GET_CHILDREN':
            return Object.assign({}, state, {
        getChildrenProperty: action.mutatedProperty
      })
    default:
      return state
    }
}

const store = Redux.createStore(MainReducer);

function mapStateToProps(state) {
    return {
        renderProperty     : state.renderProperty,
        getChildrenProperty : state.getChildrenProperty
    }
}
function mapDispatchToProps(dispatch) {
    return {
        actions: Redux.bindActionCreators(actionCreators, dispatch)
    };
}


class ProblemChild extends React.Component {
constructor() {
        super();
        this.childrenInjected = false;
        this.state = {children: null};
    }
    /**
     * Add children in setDynamicChildren() versus within render()
     */
    componentDidMount() {
        this.setDynamicChildren();
    }
    setDynamicChildren() {
        this.setState({
            children: this.getChildren()
        });
    }
    getChildren() {
        var me = this;
        console.log(this);
        return (
            <div>
                <br/>
                <button style={{marginBottom: '10px'}}
                        onClick={me._handleGetChildrenAction.bind(me)} >UI State Change Action for prop in getChildren()</button>
                <br/>
                <span>prop in getChildren(): <b>{me.props.getChildrenProperty}</b></span>
            </div>
        )
    }
    render() {
        var me = this,
            childrenInjected = me.childrenInjected;
    console.log(this.props);
        if(me.state.children && !me.childrenInjected) {
            return (
                <div >
                    <button style={{marginBottom: '10px'}}
                            onClick={me._handleRenderAction.bind(me)} > UI State Change Action for prop in render()</button>
                    <br/>
                    <span>prop in render(): <b>{me.props.renderProperty}</b></span>
                    <br/>
                    {this.state.children} <br/>
                </div>
            )
        }
        else {
            return (
                <div>placeholder, yo</div>
            )
        }
    }
  _handleRenderAction() {
        var me = this;
        store.dispatch(actionForPropInsideRender('One Fish!'));
    }
    _handleGetChildrenAction() {
        var me = this;
        store.dispatch(actionForPropInsideGetChildren('Two Fish!'));
    }
}
ProblemChild = ReactRedux.connect(mapStateToProps,mapDispatchToProps)(ProblemChild);

function actionForPropInsideRender(mutatedProperty) {
    return {
        type: 'PROBLEM_CHILD_INSIDE_RENDER',
        mutatedProperty
    }
}
function actionForPropInsideGetChildren(mutatedProperty) {
    return {
        type: 'PROBLEM_CHILD_INSIDE_GET_CHILDREN',
        mutatedProperty
    }
}

const actionCreators = {actionCreatorForPropInsideRender, actionCreatorForPropInsideGetChildren};

function actionCreatorForPropInsideRender(state, mutatedProperty) {
    let newState = state.setIn(['uiState', 'renderProperty'], mutatedProperty),
        nodeValue;

    nodeValue = newState.getIn(['uiState', 'renderProperty']);
    return newState;
}

function actionCreatorForPropInsideGetChildren(state, mutatedProperty) {
    let newState = state.setIn(['uiState', 'getChildrenProperty'], mutatedProperty),
        nodeValue;

    nodeValue = newState.getIn(['uiState', 'getChildrenProperty']);
    return newState;
}

ReactDOM.render(
    <div>
        <ReactRedux.Provider store={store}>
            <ProblemChild />
        </ReactRedux.Provider>
    </div>,
    document.getElementById('container')
);
4

1 に答える 1