单击提交按钮后,如何刷新页面或在页面中呈现内容?我试图将window.location.reload()
(我知道不是React的方式,this.forceUpdate()
的结果相同)放在提交函数(closeTicket()
,openTicketSubmit()
)中,但POST请求不这样做无法得到回应
OpenTickets.js
import React from "react";
import axios from "axios";
import CardConversation from './CardConversation.jsx';
export default class PersonList extends React.Component {
constructor(props) {
super(props);
this.state = {
people: [],
send_to_number: "",
message_body: ""
};
this.closeTicket = this.closeTicket.bind(this);
this.openTicketsReply = this.openTicketsReply.bind(this);
this.openTicketsSubmit = this.openTicketsSubmit.bind(this);
this.getPhoneNumberOpenTickets = this.getPhoneNumberOpenTickets.bind(this);
}
openTicketsReply = async e => {
this.setState({
[e.target.name]: e.target.value
});
};
getPhoneNumberOpenTickets = async e => {
this.setState({
send_to_number: e
});
};
openTicketsSubmit = async e => {
e.preventDefault();
const formData = new FormData();
formData.set("send_to_number", this.state.send_to_number.slice(1));
formData.set("message_body", this.state.message_body);
axios({
method: "post",
url: "/outgoingsms",
data: formData,
headers: { "Content-Type": "multipart/form-data" }
})
};
closeTicket = async e => {
e.preventDefault();
const formData = new FormData();
formData.set("customernum", this.state.send_to_number.slice(1));
axios({
method: "post",
url: "/closeticket",
data: formData,
headers: { "Content-Type": "multipart/form-data" }
})
};
componentDidMount() {
this.getPeopleData();
}
getPeopleData = async () => {
try {
const { data } = await axios.get(`/getongoing?limit=10`);
this.setState({ people: data });
} catch (e) {
console.log("error: ", e);
}
};
render() {
const {
closeTicket,
openTicketsSubmit,
getPhoneNumberOpenTickets,
openTicketsReply
} = this;
return this.state.people.map(person => (
<CardConversation
person={person}
closeTicket={closeTicket}
openTicketsSubmit={openTicketsSubmit}
getPhoneNumberOpenTickets={getPhoneNumberOpenTickets}
openTicketsReply={openTicketsReply}
/>
));
}
}
CardConversation.jsx
import React, { useCallback, useEffect, useState } from "react";
import { Button, Accordion, Card, Form, Row, Col } from "react-bootstrap";
import axios from "axios";
const CardConversation = ({
person,
closeTicket,
openTicketsSubmit,
getPhoneNumberOpenTickets,
openTicketsReply,
}) => {
const [conversation, setConversation] = useState([]);
// Handlers
const handleSubmit = useCallback(
e => {
openTicketsSubmit(e);
},
[openTicketsSubmit]
);
const handleCloseTicket = useCallback(
e => {
closeTicket(e);
},
[closeTicket],
);
const handleClick = useCallback(() => {
getPhoneNumberOpenTickets(person);
},
[person, getPhoneNumberOpenTickets]);
const handleChange = useCallback(
e => {
openTicketsReply(e);
},
[openTicketsReply]
);
// Methods
const fetchConversation = useCallback(async () => {
try {
const { data } = await axios.get(
"/getconvfornum?customer_number=" + person.slice(1)
);
setConversation(data);
} catch (e) {
console.log("error: ", e);
}
}, [person, conversation]);
// Effects
useEffect(() => {
fetchConversation(person)
}, [person]);
return (
<Accordion defaultActiveKey="0">
<Card>
<Card.Header>
<Accordion.Toggle as={Button} variant="button" eventKey="0">
Conversation {person.indexOf(person)+1+ ' '}
Phone number: {person}
</Accordion.Toggle>
</Card.Header>
<Accordion.Collapse eventKey="0">
<Card.Body>
{conversation.map(message => (
<div>
<p>{message.from}</p>
<p>{message.body}</p>
</div>
))}
<Form onSubmit={handleSubmit}>
<br />
<Form.Group as={Row} controlId="formPlaintextPassword">
<Col sm="10">
<Form.Control
type="text"
placeholder="Reply"
name="message_body"
onChange={handleChange}
/>
</Col>
<Button type={"submit"}
onClick={handleClick} column sm="2">
Reply
</Button>
</Form.Group>
</Form>
<Form onSubmit={handleCloseTicket}>
<Form.Group>
<Col sm="11">
<Button type={"submit"}
onClick={handleClick} column sm="4">
Close Ticket
</Button>
</Col>
</Form.Group>
</Form>
</Card.Body>
</Accordion.Collapse>
</Card>
<br />
</Accordion>
);
};
export default CardConversation;
答案 0 :(得分:2)
您可以通过更新其state
(在POST之后)来重新渲染组件:
closeTicket = async e => {
e.preventDefault();
const formData = new FormData();
formData.set("customernum", this.state.send_to_number.slice(1));
axios({
method: "post",
url: "/closeticket",
data: formData,
headers: { "Content-Type": "multipart/form-data" }
})
.then(() => {
this.setState({ /* */ })
// or
// this.forceUpdate();
})
};
答案 1 :(得分:2)
一种简单的重新渲染方法是在提交Axios请求时更改状态变量,从而导致组件自动重新渲染。 示例:
axios({...}).then(resp => {
this.setState({message_body:'',send_to_number:''}); // will cause to re-render
})
答案 2 :(得分:1)
状态更改后,React将重新渲染组件,这意味着您只需单击提交按钮即可更改状态。由于提交按钮位于PersonList组件内部,并且您还想重新加载PersonList,因此您想在单击Submit按钮时更改PersonList的状态。
这是您可能想要做的: 1)向PersonList添加“重新加载”状态,默认为false。这将告诉组件是否需要重新加载。 2)传递一个将PersonList的重载值状态设置为子组件的函数,在本例中为CardConversion。像this.setState({reload:!this.state.reload})这样的东西应该可以。 3)当您完成CardConversion中需要处理的事情后,请调用传递的函数来设置父级的状态值,然后应重新加载整个组件。
this.state = {
reload: false
...
}
...
shouldReload() {
this.setState({reload:!this.state.reload});
}
...
<CardConversation
person={person}
closeTicket={closeTicket}
openTicketsSubmit={openTicketsSubmit}
getPhoneNumberOpenTickets={getPhoneNumberOpenTickets}
openTicketsReply={openTicketsReply}
reloadParent={this.shouldReload.bind(this)}
/>
和CardConversation
const handleClick = useCallback(() => {
getPhoneNumberOpenTickets(person);
this.props.reloadParent();
},
答案 3 :(得分:1)
在opentickets.js
创建一个函数updatePeople并在该函数中调用this.getPeopleData();
例如
updatePeople = () =>{
this.getPeopleData();
}
然后进入
return this.state.people.map(person => (
<CardConversation
person={person}
closeTicket={closeTicket}
openTicketsSubmit={openTicketsSubmit}
getPhoneNumberOpenTickets={getPhoneNumberOpenTickets}
openTicketsReply={openTicketsReply}
refreshPeople = {this.updatePeople}
/>
));
在cardConversion.jsx
当您单击关闭按钮或任何使您回到openTickets的按钮时,请放置回调函数
this.props.refreshPeople();
由于您具有componentDidMount,因此每次调用componentDidMount中的内容时,它将更新信息并重新呈现
答案 4 :(得分:0)
首先,关于您没有任何数据问题,您可以检查axios以及它们如何使用post:
axios.post('/user', {
firstName: 'Fred',
lastName: 'Flintstone'
})
.then(function (response) {
// where you can setState here
console.log(response);
})
.catch(function (error) {
console.log(error);
});
主要是axios正在异步处理数据。这样,一旦调用api,React将执行下一行代码。
有关如何强制更新组件的更多讨论,您可以查看这篇文章:Can you force a React component to rerender without calling setState?,它说明了如何很好地更新组件。
答案 5 :(得分:0)
据我所知,您要执行的操作是重新加载人员列表。如果是这样,您可以通过两种方式解决该问题:
axios
API调用中,添加.then()
块并调用this.getPeopleData()
。.then()
块中,使用setState()
可以获取已添加/删除的帖子数据并更新状态,而无需重新获取人员数据。我建议您采用选择2,因为再次获取列表将需要更多时间来获取刷新的列表。
无论哪种方式,仅将this.forceUpdate()
添加到您的.then()
块都不会为您提供更新的列表。它实际上不会对用户界面做任何事情。 (尽管它可以重新渲染)
答案 6 :(得分:0)
CardConversatio.jsx
import React, { useCallback, useEffect, useState } from "react";
import { Button, Accordion, Card, Form, Row, Col } from "react-bootstrap";
import axios from "axios";
const CardConversation = ({
person,
closeTicket,
openTicketsSubmit,
getPhoneNumberOpenTickets,
openTicketsReply,
getPhoneToCloseTicket,
}) => {
const [conversation, setConversation] = useState([]);
const [trigger, fireUpdate] = useState(false);
// Handlers
const renderConversation = useCallback(() => {
return conversation.map(message => (
<div key={message.date.$date + person}>
<p>{message.from}</p>
<p>{message.body}</p>
</div>
));
}, [conversation, person]);
const fetchConversation = useCallback(async () => {
try {
const { data } = await axios.get(
"/getconvfornum?customer_number=" + person.slice(1)
);
setConversation(data);
console.log("fetch ", data);
} catch (e) {
console.log("error: ", e);
}
}, [person]);
const handleClick = useCallback(async () => {
await getPhoneNumberOpenTickets(person);
setTimeout(() => fetchConversation(person), 500);
}, [getPhoneNumberOpenTickets, person, fetchConversation]);
const handleClickClose = useCallback(async () => {
await getPhoneToCloseTicket(person);
}, [person, getPhoneToCloseTicket]);
const handleChange = useCallback(
e => {
openTicketsReply(e);
},
[openTicketsReply]
);
useEffect(() => {
console.log("effect");
fetchConversation(person);
}, [fetchConversation, person]);
return (
<Accordion defaultActiveKey="0">
<Card>
<Card.Header>
<Accordion.Toggle as={Button} variant="button" eventKey="0">
Conversation {person.indexOf(person) + 1 + " "}
Phone number: {person}
</Accordion.Toggle>
</Card.Header>
<Accordion.Collapse eventKey="0">
<Card.Body>
{renderConversation()}
<Form>
<br />
<Form.Group as={Row} controlId="formPlaintextPassword">
<Col sm="10">
<Form.Control
type="text"
placeholder="Reply"
name="message_body"
onChange={handleChange}
/>
</Col>
<Button onClick={handleClick} column sm="2">
Reply
</Button>
</Form.Group>
</Form>
<Form>
<Form.Group>
<Col sm="11">
<Button onClick={handleClickClose} column sm="4">
Close Ticket
</Button>
</Col>
</Form.Group>
</Form>
</Card.Body>
</Accordion.Collapse>
</Card>
<br />
</Accordion>
);
};
export default CardConversation;
OpenTickets.js
import React from "react";
import axios from "axios";
import CardConversation from './CardConversation.jsx';
export default class PersonList extends React.Component {
constructor(props) {
super(props);
this.state = {
people: [],
send_to_number: "",
message_body: "",
closed: false
};
this.closeTicket = this.closeTicket.bind(this);
this.openTicketsReply = this.openTicketsReply.bind(this);
this.openTicketsSubmit = this.openTicketsSubmit.bind(this);
this.getPhoneNumberOpenTickets = this.getPhoneNumberOpenTickets.bind(this);
this.getPhoneToCloseTicket = this.getPhoneToCloseTicket.bind(this);
}
openTicketsReply = async e => {
e.preventDefault();
this.setState({
message_body: e.target.value
});
};
getPhoneNumberOpenTickets = async e => {
//e.preventDefault();
this.setState({
send_to_number: e
}, async () => await this.openTicketsSubmit());
};
getPhoneToCloseTicket = async e => {
this.setState({
send_to_number: e
}, async () => this.closeTicket());
};
openTicketsSubmit = async e => {
const formData = new FormData();
formData.set("send_to_number", this.state.send_to_number.slice(1));
formData.set("message_body", this.state.message_body);
axios({
method: "post",
url: "/outgoingsms",
data: formData,
headers: { "Content-Type": "multipart/form-data" }
}).then(resp => {
this.setState({ closed: true });
}).catch(error => console.log(error))
};
closeTicket = async e => {
const formData = new FormData();
formData.set("customernum", this.state.send_to_number.slice(1));
axios({
method: "post",
url: "/closeticket",
data: formData,
headers: { "Content-Type": "multipart/form-data" }
}).then(resp => {
this.setState({ closed: true });
}).catch(error => console.log(error))
};
componentDidMount() {
this.getPeopleData();
}
getPeopleData = async () => {
try {
const { data } = await axios.get(`/getongoing?limit=10`);
this.setState({ people: data });
} catch (e) {
console.log("error: ", e);
}
};
render() {
const {
closeTicket,
getPhoneNumberOpenTickets,
openTicketsReply,
getPhoneToCloseTicket
} = this;
return this.state.people.map(person => (
<CardConversation
key={person}
person={person}
closeTicket={closeTicket}
getPhoneNumberOpenTickets={getPhoneNumberOpenTickets}
openTicketsReply={openTicketsReply}
getPhoneToCloseTicket={getPhoneToCloseTicket}
/>
));
}
}