您好,我正在尝试编辑项目后以乐观方式更新我的反应状态。我已经成功完成了删除和创建项目的操作,但似乎无法使其正常工作。但是,删除功能不使用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