将新商店状态设置为props后,react不会重新渲染

时间:2019-08-01 06:56:22

标签: reactjs redux

我正在使用react和react-redux。 我使用mapstatetoprops和mapdispatchtoprops更新了我的react组件的视图。 除非在redux存储更改后重新渲染不起作用,否则一切正常。动作调度工作正常,reducer工作正常,我可以console.log存储状态并检查差异。 最初,我使用useDispatch和useSelector,并且一切正常。但是我将其更改为mapdispatchtoprops和mapstatetoprops,以将我的代码合并到项目团队的代码中。

我试图将this.props。(whatineed)直接放入render()的return in组件中。据我了解,应该通过mapstatetoprops将存储状态传递到组件的props中。

import React, { Component } from 'react';
import { ToggleButton, ToggleButtonGroup } from 'react-bootstrap';
import { useSelector, useDispatch } from 'react-redux';
import { checked, notchecked } from '../../../actions';
import { connect } from "react-redux";
import local from './address';
import './index.css';
const mapStateToProps = state => {
    return {
      localsel : state.selectedLocal.locals
    }
  }
let mapDispatchToProps = (dispatch) => {
    return {
        check: (btn) => dispatch(checked(btn)),
        uncheck: (btn) => dispatch(notchecked(btn))
    }
}
class Seoul extends Component {
    constructor(props){
        super(props)
    }
    render(){
        var btnclicked = (e) => {
            let btnname = e.target.parentNode.getAttribute('id');
            if (e.target.checked) {
                console.log('checked');
                this.props.check(btnname);
            };
            if (!e.target.checked) {
                console.log('not checked');
                this.props.uncheck(btnname);
            };
            // HERE IS WHERE I CAN CHECK THE PASSED STORE STATE
            console.log(this.props.localsel);
            // -------------------------------------------------
        }
        return (
            <div className='localdiv localdiv1'>
                // HERE IS WHERE I WANT TO SEE MY STORE STATE
                {this.props.localsel.map(val=>{
                    return <h1>{val}</h1>
                })}
                // --------------------------------------------
                <ToggleButtonGroup className='togglebtngrp' type="checkbox">
                    <ToggleButton className='togglebtn0' onChange={btnclicked} variant="outline-secondary" value={0} id="entireseoul">Entire Seoul</ToggleButton>
                    {local.Seoul.map((value, index) => {
                        return (<ToggleButton key={index} className='togglebtn' onChange={btnclicked} variant="outline-primary" value={index + 1} id={value}>{value}</ToggleButton>)
                    })}
                </ToggleButtonGroup>
            </div>
        );
    }
}
export default connect(mapStateToProps, mapDispatchToProps)(Seoul);

此组件在父组件中导出,

import React, { Component } from 'react';
import { Jumbotron } from 'react-bootstrap';
import { Gyeongi, Incheon, Busan, Daegue, Daejeon, Sejong, Gwangju, Ulsan, Gangwon, Gyungnam, Gyungbuk, Jeonnam, Jeonbuk, Choongnam, Choongbuk, Jeju, Othercountry } from './Locals';
import Seoul from './Locals';
import './Detailsrch.css';

class Detailsrch extends Component{
    render(){
        var localselect = (e) => {
            let selector = document.getElementsByClassName('locals');
            let selector_local = document.getElementsByClassName('localdiv');
            let i = 0;
            for (let j = 0; j < selector_local.length; j++) {
                selector_local[j].style.display = 'none';
            }
            let boxclass = e.target.getAttribute('name');
            if (boxclass) document.getElementsByClassName(boxclass)[0].style.display = 'block';
            while (selector[i]) {
                selector[i].className = 'locals';
                i++;
            }
            if (e.target.className == 'localtext') {
                e.target.parentElement.className = 'locals localclick';
            } else {
                e.target.className = 'locals localclick';
            }
        }
        return (
            <Jumbotron className='searchjumbo'>
                <p>Locals</p>
                <Seoul />
                <Gyeongi />
                <Incheon />
                <Busan />
                <Daegue />
                <Daejeon />
                <Sejong />
                <Gwangju />
                <Ulsan />
                <Gangwon />
                <Gyungnam />
                <Gyungbuk />
                <Jeonnam />
                <Jeonbuk />
                <Choongnam />
                <Choongbuk />
                <Jeju />
                <Othercountry />
                <hr className='firsthr' />
                <p>type</p><hr />

                <p>career</p><hr />

                <p>country</p><hr />

                <p>sex</p>
            </Jumbotron>
        );
    }
};

export default Detailsrch;

这是我的减速器

import { combineReducers } from 'redux';
const initialstate = {
    locals: []
}
const localSelector = (state = initialstate, action) => {
    switch(action.type){
        case 'CHECKED':
            if(action.payload){
                var arr = state.locals;
                arr.push(action.payload);
                return {
                    ...state,
                    locals: arr
                };
            } else {
                return state;
            }
        case 'NOTCHECKED':
            if(action.payload){
                var arrnum = state.locals.indexOf(action.payload);
                var arr = state.locals;
                arr.splice(arrnum, 1);
                return {
                    ...state,
                    locals: arr
                };
            } else {
                return state;
            }
        default:
            return state;
    }
};

const rootReducer = combineReducers({
    selectedLocal: localSelector
});
export default rootReducer;

我希望当props值更改时,组件将重新呈现,并且我将在浏览器中看到更改。道具值已更改,但浏览器中什么都没有。

3 个答案:

答案 0 :(得分:1)

您正在按如下所示更改redux状态

 org.h2.jdbc.JdbcSQLSyntaxErrorException: Column "ad's" not found; SQL statement:
    insert  into dummyTable values (6,"ad's","df") [42122-199]
        at org.h2.message.DbException.getJdbcSQLException(DbException.java:451

)

redux状态应该是不变的。您可以在这里查看有关如何在reducer中更新redux存储的一些提示。

https://redux.js.org/recipes/structuring-reducers/immutable-update-patterns

答案 1 :(得分:0)

我看不到Detailsrch中导入了Seoul,但反之亦然Seoul被导入了Detailsrch中,根据代码和注释,我可以看到{{1 }}正在更改,并且在this.props.localsel中使用了它,因此将调用Seoul的渲染方法,并且由于Seoul中没有this.props.localsel的映射或用法,因此render方法将不被称为。

因此,如果您想重新渲染Detailsrch,则需要将Detailsrch的映射从this.props.localsel更改为Seoul并将此值作为props传递给{{1 }}应该可以正常工作。 如果仍然存在问题,请将您的代码发布到sandbox / codepen / jsfiddle,以便我们复制。

答案 2 :(得分:0)

您可能正在遭受类似this所述的帖子的困扰。为此,使组件从存储中获取更改的一种技巧(当从存储中传递状态值作为道具时)是对道具(或要在其中获取更改的道具)进行深层克隆。您可以使用JSON:

import UIKit

class chordChart: UIView {

    override init(frame: CGRect) {
        super.init(frame: frame)

        self.backgroundColor = UIColor.white

        formatChordDisplay()

    }

    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
    }

希望这会有所帮助。

P.S .:请勿克隆作为功能的道具,因为JSON会删除/忽略它们。