如何在JSX中直接使用props或state来强制组件重新渲染?

时间:2017-04-04 18:40:35

标签: javascript react-native react-redux

使用 react-redux 在反应原生应用程序中考虑以下3个JS文件(index.js,actions.js和reducer.js)。

  

index.js

import React, {Component} from 'react';
import {View, Text, ActivityIndicator} from 'react-native';
import {connect} from 'react-redux';

import {onSetup} from './actions';

class Scene01 extends Component {

    componentWillMount() {

        // dataFromOtherScene EXISTS when this Scene is created!
        // It is an OBJECT;

        this.props.onSetup(this.props.dataFromOtherScene);

    }

    render () {

        console.log('R', this.props);

        if ((this.props.paths) && (this.props.reference) && (this.props.current >= 0)) {

            const processedData = this.props.reference[Object.keys(this.props.reference)[0]].data;

            const currentPath = this.props.path[this.props.current];

            const pathData = processedData.steps[currentPath[1]].questions[currentPath[2]];

            return (
                <View>
                    <Text>{currentPath.title}</Text>
                    <Text>{pathData.anyProperty}</Text>
                    <Text>{pathData.anotherProperty}</Text>
                </View>
            );

        } else {

            return (
                <ActivityIndicator size='large' />
            );

        }

    }

}

const mapStateToProps = (state) => {
    return {
        ...state.Scene01Reducer,
        dataFromOtherScene: state.OtherScene.data
    };
};
export default connect(mapStateToProps, {
    onSetup
})(Scene01);
  

actions.js

export const ON_SETUP_SUCCESS_ACTION = 'D8129820-723B-42CE-9C2D-EA0524919E89';
export const onSetup = (data) => {

    const paths = [];
    const reference = data.reference[Object.keys(data.reference)[0]].steps;

    const steps = Object.keys(reference);

    for (let s = 0; s < steps.length; s++) {

        const step = reference[steps[s]];

        const path = [step.title, steps[s]];

        const questions = Object.keys(step.questions);

        for (let q = 0; q < questions.length; q++) {

            const fullpath = [...path, questions[q]];

            paths.push(fullpath);

        }

    }

    return {
        type: ON_SETUP_SUCCESS_ACTION,
        payload: {paths, reference}
    };

};
  

reducer.js

import {ON_SETUP_SUCCESS_ACTION} from './actions';

/**
 * Default State
 */
const DEFAULT_STATE = {
    current: null,
    paths: null,
    reference: null
};

/**
 * Reducer Body
 */
export default (state = DEFAULT_STATE, action) => {

    switch (action.type) {
        case ON_SETUP_SUCCESS_ACTION:
            return {...state, paths: action.payload.paths, reference: action.payload.reference, current: 0};
        default:
            return state;
    }

};

我尝试了很多方法...构造函数,componentWillReceiveProps,componentShouldUpdate,但在react-redux更新状态(return {type: ON_SETUP_SUCCESS_ACTION, payload: {paths, reference}};)之后,再次调用render方法,但} else {语句保持渲染。 / p>

console.log('R', this.props);显示第一次为3个reducer属性调用 null paths reference 电流

第二次,在reducer更新后,控制台显示正确设置的这3个属性......但组件没有更新......不会重新渲染。

3 个答案:

答案 0 :(得分:2)

你完全确定你的if是否具有真正的价值?

(this.props.paths)&amp;&amp; (this.props.reference)&amp;&amp; (this.props.current&gt; = 0)这可能是false,而else语句总是呈现。

如果是,您可以尝试使用componentWillMount或componentWillUpdate等生命周期方法。

另外我认为您应该使用mapStateToProps作为道具发送路径,参考和当前。

答案 1 :(得分:1)

对于这种情况,我决定将所有“onSetup”代码从操作移到const mapStateToProps范围,然后删除所有react-native组件*方法。当我需要一个开始时,我从reducer中删除了路径引用,然后直接在 mapStateToProps 范围内设置:

  

index.js

const mapStateToProps = (state) => {

    const paths = [];
    const reference = data.reference[Object.keys(data.reference)[0]].steps;

    const steps = Object.keys(reference);

    for (let s = 0; s < steps.length; s++) {
    ...


    return {
        ...state.Scene01Reducer,
        dataFromOtherScene: state.OtherScene.data,
        paths,
        reference
    };

};
  

reducer.js

const DEFAULT_STATE = {
    current: 0,
};
  

actions.js

Deleted!

这对我来说是一种解决方案。

答案 2 :(得分:0)

在完成您需要的操作后,我认为您应该尝试forceUpdate()函数,该函数在不使用setState的情况下重新呈现组件。