其他状态更改后更新状态

时间:2019-07-29 08:12:26

标签: reactjs react-redux

我有一个react类,它通过api加载列表。

pages / cars.js

class Cars extends Component{

  constructor(props) {
    super(props);

    const {getCars} = props.actions
    getCars(props.params.page, props.reducerCars.filter)

    this.handlePagination = this.handlePagination.bind(this);
  }

  render() {
    // Render list
  }

}

function mapStateToProps(state) {
  const {reducerCars} = state;
  return {
    reducerCars
  }
}

function mapDispatchToProps(dispatch){
  return{
    actions: bindActionCreators(Actions, dispatch)
  }
}

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

页面上有一个开关可以过滤列表。

<FormControlLabel
  control={
    <Switch value="5" onChange={this.handleChange.bind(this,5)} color="primary" />
  }
  labelPlacement="start"
  label="Renovate"
/>

激活此开关后,存储中的状态将被更新。

handleChange(name, event) {
  const newFilter = this.props.reducerCars.filter;

  if(event.target.checked === true) {
    newFilter.push(name);
  } else {
    var index = newFilter.indexOf(name);
    newFilter.splice(index, 1);
  }

  this.props.actions.filter(newFilter);

}

actions / actions.js

export function filter(filter) {
  return{
    type: CAR_FILTER,
    filter: filter
  }
}

reducers / reducers.js

if (action.type === CAR_FILTER) {
  return Object.assign({}, state, {
    filter: action.filter
  });
}

仅在切换之后,才应刷新api。最好的方法是什么?

我尝试检查是否在componentWillReceiveProps()中更新了商店,但nextprops与当前props相同:

componentWillReceiveProps(nextProps){
  console.log(this.props.reducerCars.filter);
  console.log(nextProps.reducerCars.filter);

  if(this.props.reducerCars.filter !=== nextProps.reducerCars.filter) {

  }
}

更新开关后,我可以在filter动作中进行分派。但是比我还需要currentPage传递给getCars(currentPage,filter);还是使用Redux订阅选项?

这里最好的React / Redux解决方案是什么?

完整代码可在此处找到:https://github.com/emkedouwe/aircoolednetwork

3 个答案:

答案 0 :(得分:0)

有两种方法可以执行此操作。一种正在使用

df = pd.DataFrame(d)
s = df.pop('id')
df1 = pd.DataFrame.from_records(df.stack().values, index=np.repeat(s, df.shape[1]))

Out[1051]:
     overspeedCount  speed  voltage
id
001  2               10     12.3
001  1               50     12.2
001  1               50     12.2
002  1               13     12.1
002  0               40     12.1
002  3               25     12.2

如果您的“ mapStateToProps”中有该状态,则该nextProps将为您提供当前状态。

第二种方法是,您可以在saga中间件中查看它的更改,然后更新状态,然后可以在商店中更新状态。

答案 1 :(得分:0)

import React, { Component } from 'react';
import { bindActionCreators } from 'redux';
import { connect } from 'react-redux';
import FormGroup from '@material-ui/core/FormGroup';
import FormControlLabel from '@material-ui/core/FormControlLabel';
import Switch from '@material-ui/core/Switch';
import * as Actions from '../actions/actions';
import { CSSTransition, TransitionGroup } from 'react-transition-group';
import CarTeaser from './../components/carteaser.js';
import Pagination from './../components/pagination.js';

class Cars extends Component {

    constructor( props ) {
        super( props );

        const { getCars } = props.actions
        getCars( props.params.page, props.reducerCars.filter )

        this.handlePagination = this.handlePagination.bind( this );
    }

    componentWillReceiveProps( nextProps ) {
        if( this.props.params.page !== nextProps.params.page ) {
            const { getCars } = nextProps.actions
            getCars( nextProps.params.page, this.props.reducerCars.filter )
        }

        console.log( this.props.reducerCars.filter );
        console.log( nextProps.reducerCars.filter );
    }

    filterTest = (testProp) => {
        if(testProp.reducerCars.filter.length !== 0){
            testProp.actions.filter(testProp.reducerCars.filter);
        }
    }

    handleChange( name, event ) {
        const newFilter = this.props.reducerCars.filter;

        if( event.target.checked === true ) {
            newFilter.push( name );
        } else {
            var index = newFilter.indexOf( name );
            newFilter.splice( index, 1 );
        }

        this.props.actions.filter( newFilter );
        this.filterTest(this.props);
    }

    handlePagination( pageNumber ) {
        this.props.router.push( '/cars/' + pageNumber );
    }

    render() {

        const { reducerCars } = this.props;
        const { currentPage, noOfPages, isLoading } = reducerCars;

        if( isLoading ) {
            return (
                <div>Loading...</div>
            )
        } else {
            return (
                <div className="Cars">
                    <div className="container py-3">
                        <FormGroup aria-label="position" name="position" row>
                            <FormControlLabel
                                control={
                                    <Switch value="3" onChange={this.handleChange.bind( this, 3 )} color="primary"/>
                                }
                                labelPlacement="start"
                                label="Original"
                            />
                            <FormControlLabel
                                control={
                                    <Switch value="4" onChange={this.handleChange.bind( this, 4 )} color="primary"/>
                                }
                                labelPlacement="start"
                                label="Custom"
                            />
                            <FormControlLabel
                                control={
                                    <Switch value="5" onChange={this.handleChange.bind( this, 5 )} color="primary"/>
                                }
                                labelPlacement="start"
                                label="Renovate"
                            />
                        </FormGroup>
                    </div>
                    <div className="container my-3">
                        <TransitionGroup className="row">
                            {reducerCars.cars.map( ( car ) => {
                                return (
                                    <CSSTransition
                                        key={car.id}
                                        timeout={0}
                                        classNames="item"
                                    >
                                        <CarTeaser key={car.id} car={car}/>
                                    </CSSTransition>
                                )
                            } )}
                        </TransitionGroup>
                        <div className="container">
                            <Pagination
                                total={parseInt( noOfPages )}
                                current={parseInt( currentPage )}
                                prevText="Prev"
                                showPages={true}
                                nextText="Next"
                                onClickPage={this.handlePagination}
                                baseClassName="pagination justify-content-center"
                            />
                        </div>
                    </div>
                </div>
            );
        }
    }

}

function mapStateToProps( state ) {
    const { reducerCars } = state;
    return {
        reducerCars
    }
}

function mapDispatchToProps( dispatch ) {
    return {
        actions: bindActionCreators( Actions, dispatch )
    }
}

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

答案 2 :(得分:0)

最好像这样更改过滤器动作:

export function filter(filter) {
  return (dispatch, getState) => {
    dispatch({ type: CAR_FILTER, filter: filter });

    const state = getState();

    dispatch(getCars(state.reducerCars.currentPage, filter));
  };
}