Consider the 3 following JS files (index.js, actions.js and reducer.js) in a react-native application using react-redux .
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;
}
};
I tried many approaches... constructor, componentWillReceiveProps, componentShouldUpdate but after the react-redux updates the state ( return {type: ON_SETUP_SUCCESS_ACTION, payload: {paths, reference}};
), the render method is called again but the } else {
statement keeps rendered.
The console.log('R', this.props);
shows the first time it is called null for the 3 reducers properties: paths , reference and current .
The second time, after reducer update, the console shows these 3 properties properlly set... but the component does not update... does not re-render.
are you completely sure that your if is with a true value?
(this.props.paths) && (this.props.reference) && (this.props.current >= 0) this could be false and the else statement would always render.
If it is, you could try to use a lifecycle method like componentWillMount or componentWillUpdate.
Also i think that you should use mapStateToProps to send paths, reference and current as a prop.
For this scenario, I decided to move all the "onSetup" code from actions to const mapStateToProps
scope and then I remove all react-native component* methods. As I need a start, I removed the paths and reference from the reducer and set then directly in mapStateToProps scope:
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!
This worked for me as a solution.
看完您需要的内容后,我认为您应该尝试使用forceUpdate()
函数来重新渲染该组件而不使用setState。
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.