简体   繁体   English

React Redux状态正在更新,但组件属性未更新

[英]React Redux State is Updating, but Component Props Not Updating

Disclaimer: this is my first react app and im a cs student thats still learning 免责声明:这是我的第一个React应用,我是正在学习的CS学生

I did some console logs and the the props and nextprops are correct, but it doesnt render correctly unless interacted with. 我做了一些控制台日志,并且props和nextprops是正确的,但是除非与之交互,否则它无法正确呈现。

I have to click a button twice before the opacity changes and the opacity of the other buttons doesnt update to 1. 我必须单击两次按钮,然后更改不透明度,而其他按钮的不透明度不会更新为1。

I've gone through quite a few google searches and tried a few things, but none of them worked. 我经历了很多Google搜索并尝试了一些方法,但是没有一个起作用。

Class with 2 instances of the button from WeekMenu.js 使用WeekMenu.js中的2个按钮实例的类

class WeekMenu extends Component{
render(){
    return(
        <View style={styles.container}>
            <TouchableOpacity 
            style={this.props.daysOfWeek[0] ? {opacity: 0.5} : {opacity: 1}}
            onPress={() =>this.props.dayClicked(0)}
            >
                <View style={styles.left}>
                    <Text style={styles.text}>S</Text>
                </View>
            </TouchableOpacity>
            <TouchableOpacity 
            style={this.props.daysOfWeek[1] ? {opacity: 0.5} : {opacity: 1}}
            onPress={() =>this.props.dayClicked(1)}
            >
                <View style={styles.middle}>
                    <Text style={styles.text}>M</Text>
                </View>
            </TouchableOpacity>

WeekMenu.js contiued WeekMenu.js继续

function mapStateToProps(state){
    return{
        daysOfWeek: state.daysOfWeek
    }
}
function mapDispatchToProps(dispatch){
    return{
        dayClicked: (value) => dispatch({type: 'DAY_CLICKED', value})
    }
}
export default connect(mapStateToProps, mapDispatchToProps)(WeekMenu)

App.js App.js

const initialState = {
    daysOfWeek: [0, 0, 0, 0, 0, 0, 1]
}
changeActiveDay = (day) => {
    newDaysOfWeek = new Array(7).fill(0)
    newDaysOfWeek[day] = 1
    return newDaysOfWeek
}
const reducer = (state = initialState, action) => {
    switch (action.type) {
        case 'DAY_CLICKED':
            return {
                ...state,
                daysOfWeek: changeActiveDay(action.value)
            }
        default:
            return state
    }
}
const store = createStore(reducer)

Update #1: 更新#1:

class WeekMenu extends Component{
state = {
    daysOfWeek: this.props.daysOfWeek
}

componentDidUpdate(prevProps){
    if(prevProps.daysOfWeek !== this.props.daysOfWeek)
        this.setState({daysOfWeek: this.props.daysOfWeek})
}

render(){
    return(
        <View style={styles.container}>
            <TouchableOpacity 
            style={this.state.daysOfWeek[0] ? {opacity: 0.5} : {opacity: 1}}
            onPress={() => this.props.dayClicked(0)}
            >
                <View style={styles.left}>
                    <Text style={styles.text}>S</Text>
                </View>
            </TouchableOpacity>
            ...    

您需要使用componentWillUpdate()shouldComponentUpdate()监听更改,并使用nextPropsprevState作为参数来nextProps更改。

You can use lifecycle to set your props to state. 您可以使用生命周期来设置道具的状态。

componentDidUpdate(prevProps, prevState) { 
  this.setDaysOfWeek(prevProps, prevState)
}


setDaysOfWeek(prevProps,state) {
  if(prevProps.daysOfWeek !== state.daysOfWeek){
    this.setState({daysOfWeek: prevProps.daysOfWeek})   
  }
}

Solution from peer: 来自同行的解决方案:

Include this line of code before the style is set to force a rerender by changing an unused key to a random number 在样式设置为通过将未使用的键更改为随机数来强制重新渲染之前,请包括以下代码行

key={String(Math.random())}

As in this example: 如本例所示:

<TouchableOpacity
    key={String(Math.random())}
    style={this.state.daysOfWeek[index] ? {opacity: 0.5} : {opacity: 1}}
    onPress={() => this.props.dayClicked(index)}
>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM