使用React,Redux更新项目列表。和Redux表格

时间:2017-12-29 20:01:01

标签: reactjs redux redux-form

如何在完成添加马动作后更新马匹列表?

我认为CreateHorse中的reloadHorseList在createHorse动作完成之前运行,所以有时候我会在列表中看到新的马,有时候不会。完整重新加载始终显示更新。

马组件

...
import { getHorses } from '../../actions';
import ListHorses from './ListHorses';
import CreateHorse from './forms/createHorseForm';

class Horses extends React.Component {

  constructor(props) {
    super(props);

    this.state = {
      ...
    };
    this.reloadHorseList = this.reloadHorseList.bind(this);
  }

  componentDidMount() {
     this.reloadHorseList();
  }

  reloadHorseList() {
    this.props.getHorses(this.props.current_user.selected_stable);
  }

  render() {
    return (
      <div className="content page-content-wrapper1">

        <CreateHorse
          current_user={this.props.current_user}
          reloadHorseList={this.reloadHorseList}
        />
        <ListHorses
          current_user={this.props.current_user}
          horses={this.props.horses}
        />
      </div>
    );
  }
}

function mapStateToProps(state) {
  return {
    horses: state.horses
  };
}

function mapDispatchToProps(dispatch) {
  return bindActionCreators(
    {
      getHorses: getHorses
    },
    dispatch
  );
}

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

创建马形式

...
import { Field, reduxForm, getFormValues } from 'redux-form';
import {
  createHorse,
  getHorseSelect,
  updateHorseCount
} from '../../../actions';
import { connect } from 'react-redux';

const renderField = (...
);

class CreateHorse extends Component {
  constructor(props) {
    super(props);
      this.state = {
      ...
    };
    this.setMessage = this.setMessage.bind(this);
  }


  onSubmit(props) {
    //let p = this.props.reloadHorseList;
    try {
      this.props.createHorse(props, this.setMessage);

      //running before I have finished creating my horse
      this.props.reloadHorseList();

    } catch (err) {
      ...
    }
  }


  render() {
    const { handleSubmit } = this.props;

    return (
      <div>
        ...
        {this.state.displayHorseCreateForm && (
          <div>
            <h4 className="header-content">Add Horse</h4>
            <p> * required field</p>

            <form onSubmit={handleSubmit(this.onSubmit.bind(this))}>

              // fields here

              <button type="submit" className="btn btn-primary">
                Submit
              </button>
            </form>
          </div>
        )}
      </div>
    );
  }
}
function validate(values) {
 ...
}

function mapStateToProps(state) {
  ---
}

export default connect(mapStateToProps, {
  createHorse,
  getHorseSelect,
  updateHorseCount
})(
  reduxForm({
    form: 'HorseCreatetForm',
    initialValues: {
      ...
    },
    validate
  })(CreateHorse)
);

//create horse action
export const createHorse = (props, setMessage) => async dispatch => {
  try {
    const request = await axios.post(`/api/horse/create`, props);
    return {
      type: CREATED_HORSE,
      payload: request.data
    };
  } catch (err) {
   ...
  }
};

ListHorses

...
import { deleteHorse } from '../../actions';

class HorsesList extends React.Component {

  render() {
    let horses = this.props.horses;
    let horseCount = this.props.horse_count;
    return (
      <div className="content">
        horse count: {horseCount}
        <ul className="list-inline box-body">
          {horseCount > 0 &&
            horses.map((horse, key) => (
              <li key={key}>
                ...//listing here
              </li>
            ))}
        </ul>
      </div>
    );
  }
}

function mapStateToProps(state) {
  return {
    horse_count: state.horse_count
  };
}

function mapDispatchToProps(dispatch) {
  return bindActionCreators(
    {
      ...
    },
    dispatch
  );
}

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

2 个答案:

答案 0 :(得分:1)

对我有用的解决方案是向CreateHorse组件发送回调,以发送到运行Horse组件操作的createHorse动作到getHorses。

class Horses extends React.Component {
  constructor(props) {
    super(props);

    this.state = {
      horses: this.props.horses,
    };
    this.reloadHorses = this.reloadHorses.bind(this);
  }

  componentDidMount(prevProps) {
    this.props.getHorses(this.props.current_user.selected_stable);
  }

  reloadHorses = () => {
    this.props.getHorses(this.props.current_user.selected_stable);
  };

  ...

  <CreateHorse
    current_user={this.props.current_user}
    reloadHorses={this.reloadHorses}
  />
  <ListHorses
    horses={this.props.horses}
  />

... 

function mapStateToProps(state) {
  return {
    horses: state.horses
  };
}

function mapDispatchToProps(dispatch) {
  return bindActionCreators(
    {
      getHorses: getHorses
    },
    dispatch
  );
}

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

然后在CreateHorse组件

onSubmit(props) {

      this.props.createHorse(props, this.setMessage, this.props.reloadHorses);

    }
  }

然后在createHorse动作中

export const createHorse = (
  props,
  setMessage,
  reloadHorses
) => async dispatch => {
  try {
    const request = await axios.post(`/api/horse/create`, props);

    reloadHorses();

    return {
      type: CREATED_HORSE,
      payload: request.data
    };
  } catch (err) {
   ...
  }
};

答案 1 :(得分:0)

此时您应该发布实际代码。要触发组件重新渲染,您需要更改它的状态。我建议将您的道具从redux设置为本地状态并从中呈现您的列表。您还需要使用componentWillRecieveProps();

 componentDidMount() {
    this.reloadHorseList();
    this.setState=({list: this.props.horseList});
  }

componentWillRecieveProps(nextProps){
    this.setState=({list: nextProps.horseList})
}

您认为组件首先完成加载是正确的。因此,您需要使用componentWillRecieveProps生命周期钩子。

或者,如果您使用带有redux的mapStateToProps(),则当mapStateToProps()中的任何内容发生更改时,您的组件应该重新渲染。