【问题标题】:Props not being updated when Redux action is called调用 Redux 操作时没有更新道具
【发布时间】:2018-02-06 18:24:16
【问题描述】:

只是一个免责声明 - 当我的主要组件中有问题的功能时,我的代码可以正常工作。在我导出它之后,它停止了应有的行为。我的理论是因为某些道具没有正确更新。

无论如何,我有一个组件,单击它后它开始侦听窗口对象并将适当的存储元素设置为“true”,并根据单击的下一个对象进行相应的操作。点击不正确的对象后,store 应该恢复为 false,并且确实如此,但是 props 仍然是“true”,如下面的屏幕截图所示。

我该如何解决这个问题?也许有一种方法可以让函数将存储作为参数而不是道具?或者我不正确地调用动作或我完全错过了什么?

代码如下:

主要组件(相关部分?):

import React from 'react';
import { connect } from 'react-redux'
import { bindActionCreators } from 'redux'

import {activate} from '../../actions/inventory'
import { setModalContent, setModalState } from '../../actions/modal';
import inventoryReducer from '../../reducers/inventory';

import {chainMechanics} from './itemMechanics/chainMechanics';


class ItemRenderer extends React.Component{

    handleBoltcuttersClicked(){
        this.props.activate('boltcutters', true);
        setTimeout(() => chainMechanics(this.props), 100)
    }

    inventoryItemRender(){
        let inventoryItem = null;
        if(this.props.inventory.items.boltcutters){
            inventoryItem = <a className={this.props.inventory.activeItem.boltcutters ? "ghost-button items active " : "ghost-button items"} href="#" id='boltcuttersId' onClick={() => this.handleBoltcuttersClicked()}>Boltcutters</a>
        }
        return inventoryItem;
    }

    render(){
        let renderItems = this.inventoryItemRender();
        return(
            <div>
                {renderItems}
            </div>
        )
    }
}

const mapStateToProps = (state) => {
    return {
        level: state.level,
        inventory: state.inventory
    }
}

function mapDispatchToProps(dispatch) {
    //dispatch w propsach
    return(
        bindActionCreators({activate: activate, setModalState: setModalState, setModalContent: setModalContent }, dispatch)
    ) 
  }

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

功能有问题的文件:

import {activate} from '../../../actions/inventory'
import { setModalContent, setModalState } from '../../../actions/modal';

export function chainMechanics(props){
    let clickedElement;
    window.onclick = ((e)=>{
        console.log(clickedElement, 'clickedelement', props.inventory.activeItem.boltcutters)
        if(props.inventory.activeItem.boltcutters===true){
            clickedElement = e.target;
            if(clickedElement.id === 'chainChainedDoor'){
                props.activate('boltcutters', false);
                props.setModalContent('Chain_Broken');
                props.setModalState(true);
            } else if(clickedElement.id === 'boltcuttersId'){
                console.log('foo')
            } else  {
                props.activate('boltcutters', false);
                props.setModalContent('Cant_Use');
                props.setModalState(true);
                console.log("props.inventory.activeItem.boltcutters", props.inventory.activeItem.boltcutters); 
            }
        }
    })
}

我的行动:

const inventoryReducer = (state = inventoryDefaultState, action) => {
    switch (action.type) {
        case 'ACTIVE':
            console.log(action)
            return {
                ...state,
                activeItem: {
                    ...state.activeItem,
                    [action.item]: action.isActive
                }
            }
        default:
            return state;
    }
}

我如何配置商店:

export default () => {
    const store = createStore(
        combineReducers({
            level: levelReducer,
            modal: modalReducer,
            inventory: inventoryReducer,
            styles: stylesReducer
        }),
        applyMiddleware(thunk)
    )
    return store;
}

我相信这就是所有需要的东西吗?如果没有,请告诉我,我已经尝试了很长时间。

截图:

【问题讨论】:

  • 当我在 if 语句的末尾执行“props.inventory.activeItem.boltcutters = false;”时它有点工作,但我想那很丑
  • 用 props.inventory.activeItem.boltcutters = false;你正在改变状态,在 Redux 中你不应该这样做
  • 我知道我不应该这样做,但这是我必须让它发挥作用的唯一选择。到目前为止,我无法找到其他解决方案,没有人指出我正确的方向/我做错了什么
  • 看看我的回答,希望对你有帮助

标签: javascript reactjs redux react-redux


【解决方案1】:

你可以使用 React 的函数componentWillReceiveProps。这将触发像这样的重新渲染(并且还使用下一个道具/状态):

componentWillReceiveProps(next) {
    console.log(next);
    this.inventoryItemRender(next);
}

inventoryItemRender(next){
        const inventory = next.inventory ? next.inventory : this.props.inventory;
        let inventoryItem = null;
        if(inventory.items.boltcutters){
            inventoryItem = <a className={inventory.activeItem.boltcutters ? "ghost-button items active " : "ghost-button items"} href="#" id='boltcuttersId' onClick={(next) => this.handleBoltcuttersClicked(next)}>Boltcutters</a>
        }
        return inventoryItem;
}

handleBoltcuttersClicked(props){
        this.props.activate('boltcutters', true);
        setTimeout(() => chainMechanics(props), 100)
    }

【讨论】:

  • 当我以这种方式触发重新渲染时应用程序崩溃。 "> 29 | if(inventory.items.boltcutters){ " 在这种情况下是未定义的断线钳。
  • 您可以尝试记录下一个如我的答案编辑中所示的内容吗?检查那里是否存在库存
  • 对不起,我打错了,漏掉了一个点。现在它可以工作了,但是遗憾的是,道具仍然没有随着功能更新。但也许是因为我以这种方式传递了 chainMechanics(this.props) 它。我应该将此函数移到 componentWillReceiveProps 中吗?
  • 我再次编辑了答案并添加了 handleBoltcuttersClicked 以获取作为参数传递的道具。我没有测试代码,但它应该像那样工作。您将inventoryItem 中使用的道具传递给handleBoltcuttersClicked,然后将其传递给chainMechanics
  • 有一些错误,但我会尽快解决它们,因为我需要处理一些重要的工作,如果我能告诉你,我会告诉你
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-07-19
  • 1970-01-01
  • 2023-03-18
  • 2020-08-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多