更新乐观地响应redux状态

时间:2020-06-23 08:45:31

标签: reactjs redux

您好,我正在尝试编辑项目后以乐观方式更新我的反应状态。我已经成功完成了删除和创建项目的操作,但似乎无法使其正常工作。但是,删除功能不使用redux,而编辑使用redux,我对redux的处理方式如何?

这是我删除项目成功完成的操作:SearchAndDisplay.js

设置optimisticTournaments状态,然后在handleDelete内部对其进行更新

import { connect } from 'react-redux';
import { fetchTournaments } from '../actions/tournaments';
import Item from './Item';
import EditTournament from './EditTournament';
import axios from 'axios';

import '../styles/Item.css';

class SearchAndDisplay extends React.PureComponent {
  componentDidMount() {
    this.props.fetchTournaments();
  }

  state = {
    searchCriteria: '',
    optimisticTournaments: null,
    notFound: false
  };

  handleChange = event => {
    this.setState({
      searchCriteria: event.target.value
    });
  };

  async handleDelete(id) {
    const url = `http://localhost:4000/tournaments/`;

    // optimistically remove element
    this.setState({
      optimisticTournaments: this.props.tournaments.filter(
        item => item.id !== id
      )
    });

    await axios
      .delete(url + id)
      .then(res => {
        console.log(res.data);
      })
      .catch(err => {
        console.log(err);
      });
  }

  formatDate(date) {
    let options = {
      year: 'numeric',
      month: 'numeric',
      day: 'numeric',
      hour: 'numeric',
      minute: 'numeric',
      second: 'numeric',
      hour12: false
    };

    let newDate = new Date(Date.parse(date));
    let format = new Intl.DateTimeFormat('default', options).format(newDate);

    return format;
  }

  handleChange = event => {
    this.setState({ searchCriteria: event.target.value });
  };

  renderItems() {
    const { searchCriteria } = this.state;

    let tournmentsArray =
      this.state.optimisticTournaments || this.props.tournaments;

    const filterTournaments = tournmentsArray.filter(item =>
      item.name.includes(searchCriteria)
    );

    if (filterTournaments.length === 0) {
      return (
        <div className="textWrapper">
          Something went wrong.
          <br />
          <button
            className="notFoundButton"
            onClick={() => {
              this.setState({ searchCriteria: '' });
            }}
          >
            Retry
          </button>
        </div>
      );
    }

    return filterTournaments.map((item, index) => (
      <Item
        key={index}
        name={item.name}
        organizer={item.organizer}
        participants={Object.values(item.participants)}
        game={item.game}
        start={this.formatDate(item.startDate)}
      >
        <div className="buttonBar">
          <EditTournament id={item.id} name={item.name} />
          <button
            className="button"
            onClick={() => {
              if (
                window.confirm('Are you sure you want to delete this item?')
              ) {
                this.handleDelete(item.id);
              }
            }}
          >
            Delete
          </button>
        </div>
      </Item>
    ));
  }

  render() {
    if (this.props.tournaments.length === 0) {
      return <div className="textWrapper">Loading tournaments...</div>;
    }

    return (
      <div className="container">
        <input
          onChange={this.handleChange}
          className="input"
          placeholder="Search..."
          id="searchField"
          value={this.state.searchCriteria}
        />
        <div className="row">{this.renderItems()}</div>
      </div>
    );
  }
}

function mapStateToProps({ tournaments }) {
  return {
    tournaments: Object.values(tournaments).flat()
  };
}

export default connect(mapStateToProps, {
  fetchTournaments
})(SearchAndDisplay);

有问题的组件EditTournament.js

import React from 'react';
import PromptForm from './PromptForm';
import _ from 'lodash';
import { connect } from 'react-redux';
import { fetchTournament, editTournaments } from '../actions/tournaments';

class EditTournament extends React.Component {
  componentDidMount() {
    this.props.fetchTournament(this.props.id);
  }

  onSubmit = formValues => {
    this.props.editTournaments(this.props.id, formValues);
  };

  render() {
    return (
      <PromptForm
        initialValues={{ name: this.props.name }}
        onSubmit={this.onSubmit}
      />
    );
  }
}

const mapStateToProps = (ownProps, state) => {
  return { tournaments: state.tournament };
};

export default connect(mapStateToProps, { editTournaments, fetchTournament })(
  EditTournament
);

PromptForm.js-导入到EditTournament.js

import React from 'react';
import { reduxForm, Field } from 'redux-form';
import '../styles/promptForms.css';
import '../styles/Header.css';

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

    this.state = {
      showHide: false
    };
  }

  button() {
    return (
      <div>
        <button
          className="button"
          onClick={() => this.setState({ showHide: true })}
        >
          Edit
        </button>
      </div>
    );
  }

  renderInput = ({ input, label }) => {
    return (
      <div>
        <label>{label}</label>
        <br />
        <input className="promptInput" {...input} autoComplete="off" />
      </div>
    );
  };

  onSubmit = formValues => {
    this.props.onSubmit(formValues);
  };

  render() {
    const { showHide } = this.state;

    return (
      <React.Fragment>
        <div className={`overlay ${showHide ? 'toggle' : ''} `} />

        <div className={`promptBox ${showHide ? 'toggle' : ''} `}>
          <h3>localhost:3000 says</h3>
          <form onSubmit={this.props.handleSubmit(this.onSubmit)}>
            <Field
              name="name"
              component={this.renderInput}
              label="Enter Tournament:"
            />

            <button
              className="okayButton"
              onClick={() => this.setState({ showHide: false })}
            >
              OK
            </button>
          </form>
          <button
            className="cancelButton"
            onClick={() => this.setState({ showHide: false })}
          >
            Cancel
          </button>
        </div>
        {this.button()}
      </React.Fragment>
    );
  }
}

export default reduxForm({
  form: 'promptForm'
})(PromptForm);

用于编辑和获取锦标赛的Redux操作:

export const fetchTournaments = () => async dispatch => {
  const response = await axios.get(API_TOURNAMENTS_URL);

  dispatch({
    type: FETCH_TOURNAMENTS,
    payload: response.data.flat()
  });
};

export const fetchTournament = id => async dispatch => {
  const response = await axios.get(`http://localhost:4000/tournaments/${id}`);

  dispatch({ type: FETCH_TOURNAMENT, payload: response.data });
};

export const createTournaments = formValues => async dispatch => {
  const response = await axios.post(API_TOURNAMENTS_URL, {
    ...formValues
  });

  dispatch({ type: CREATE_TOURNAMENT, payload: response.data });
};

export const editTournaments = (id, formValues) => async dispatch => {
  const response = await axios.patch(
    `http://localhost:4000/tournaments/${id}`,
    formValues
  );
  console.log('edited', id);

  dispatch({ type: EDIT_TOURNAMENT, payload: response.data });
};

console.logged result after I submit an edit

动作文件中的Console.log(action),它显示在我编辑后正在分发正确的数据,我只在编辑name,所以只有名称更改。

{type: "edit_tournament", payload: {…}}
payload: {id: "4120b9a0-9546-4858-b767-411dbdc99d7a", name: "Non Soluta Cumque In", organizer: "Illo Sint", game: "League of Legends", participants: {…}, …}
type: "edit_tournament"
__proto__: Object

0 个答案:

没有答案