Api.js
import React from 'react';
import './Api.scss';
import ProfileCard from 'components/Card/ProfileCard.jsx';
import Modal from 'react-awesome-modal';
class Api extends React.Component {
constructor(props) {
super(props);
this.state = {
title : '',
content: '',
img: '',
data: []
}
}
OnFileChange = (event) => {
this.setState({img: event.target.files[0]});
}
onTitleChange = (event) => {
this.setState({title: event.target.value})
}
onContentChange = (event) => {
this.setState({content: event.target.value})
}
resetForm = () => {
document.getElementById('title').value = '';
document.getElementById('content').value = '';
document.getElementById('img').value = '';
}
openModal() {
this.setState({
visible : true
});
}
closeModal() {
this.setState({
visible : false
});
}
componentDidMount() {
fetch('http://127.0.0.1:8000/get_profile/')
.then(response => response.json())
.then(res => this.setState({ data: res }));
}
SubmitProfile = (event) => {
let formData = new FormData();
formData.append('img',this.state.img);
formData.append('title',this.state.title);
formData.append('content',this.state.content);
fetch('http://127.0.0.1:8000/post_profile/', {
method: 'post',
headers: {
Accept: 'application/json, text/plain, */*'
},
body:formData,
})
.then(response => response.json())
.then(res => {
if (res.code === 200){
this.componentDidMount()
this.resetForm()
this.closeModal()
}
console.log(res);
})
}
elasticSearch = (event) => {
fetch('http://127.0.0.1:8000/search/', {
method: 'post',
headers:{'Content-Type': 'application/json'},
body: JSON.stringify({
q: event.target.value
})
})
.then(response => response.json())
.then(res => {
console.log(res)
this.setState({ data: res })
});
}
render(){
return (
<div className="api-body">
<section>
<div className="tc pa2">
<input
type="button"
className="br2 center ph3 pv2 input-reset ba b--black bg-transparent grow pointer f6 dib"
value="Post"
onClick={() => this.openModal()}
/>
<input
className="db ma3 q center border-box hover-black w-100 measure ba b--black-20 pa2 br2 mb2"
type="text"
name="q"
id="q"
placeholder="search here .."
onChange = {this.elasticSearch}
/>
</div>
<Modal
visible={this.state.visible}
width="400"
height="300"
effect="fadeInDown"
onClickAway={() => this.closeModal()}
>
<div className="mv3 pa3">
<label className="db fw6 lh-copy f6" htmlFor="password">Title</label>
<input
className="db border-box hover-black w-100 measure ba b--black-20 pa2 br2 mb2"
type="text"
name="title"
id="title"
onChange={this.onTitleChange}
/>
</div>
<div className="mv3 pa3 mt-1">
<label htmlFor="comment" className="f6 b db mb2">Contents </label>
<textarea
id="content"
name="content"
className="db border-box hover-black w-100 measure ba b--black-20 pa2 br2 mb2"
aria-describedby="content-desc"
onChange={this.onContentChange}>
</textarea>
</div>
<div className="mv3 pa3 mt-1">
<input
type="file"
multiple = {false}
id="img"
name="img"
ref={(input) => { this.inpuElement = input; }}
accept=".jpg,.jpeg,.png,.pdf,.doc"
onChange={this.OnFileChange}
/>
<input
type="button"
className="br2 center ph3 pv2 input-reset ba b--black bg-transparent grow pointer f6 dib"
value="Submit"
onClick={this.SubmitProfile}
/>
</div>
</Modal>
</section>
<ProfileCard data={this.state.data} />
</div>
)
}
}
export default Api;
ProfileCard.js
import React from 'react';
class ProfileCard extends React.Component {
constructor(props){
super(props)
this.state = {
data : []
}
}
deleteProfile = id => e => {
fetch('http://127.0.0.1:8000/delete_profile/', {
method: 'post',
headers:{'Content-Type': 'application/json'},
body: JSON.stringify({
id: id
})
})
.then(response => response.json())
.then(res => {
if (res.code === 200){
this.componentDidMount()
}
console.log(res)
})
}
render(){
return (
<div>
{
this.props.data.map((user,i) => {
return (
<article className='mw5 tc bg-white dib br3 pa3 ma3 pa4-ns mv3 ba b--black-10 shadow-5 pc-scroll pointer' key={i}>
<div className="tc">
<img
src={"http://127.0.0.1:8000" + user.photo}
className="br-100 h3 w3 dib"
alt="profile pic"
onDoubleClick = {this.deleteProfile(user.id)}
/>
<h1 className="f4">{user.title}</h1>
<hr className="mw3 bb bw1 b--black-10" />
</div>
<p className="lh-copy measure center f6 black-70">
{user.content}
</p>
</article>
);
})
}
</div>
);
}
}
export default ProfileCard;
在我的ProfileCard中有一个功能deleteProfile,如您所见,以及我的componentDidMount 在Api组件上。我想在deleteProfile执行后立即调用componentDidMount。
我找不到任何适当的方法来执行此操作。 如果我直接发送componentDidMount也将无法正常工作 因为我正在将res分配给州。
答案 0 :(得分:2)
componentDidMount
是生命周期挂钩。不应直接调用它。语义上正确的方法是提供一种可以在两个地方重用的方法:
componentDidMount() {
this.fetchData();
}
fetchData() {
return fetch('http://127.0.0.1:8000/get_profile/')
.then(response => response.json())
.then(res => this.setState({ data: res }));
}
SubmitProfile = (event) => {
...
.then(res => {
if (res.code === 200){
return this.fetchData()
...
}
这也有利于可测试性。 fetchData
可以与组件生命周期分开进行测试。此外,方法应返回promise,所有promise应链接在一起。
这里的问题是关注点分离。 ProfileCard
应该为dumb component,并将所有工作委托给父母。此方法属于父Api
组件:
deleteProfile = id => {
fetch('http://127.0.0.1:8000/delete_profile/', ...)
...
.then(res => {
if (res.code === 200){
this.fetchData()
}
})
}
应将其传递给子组件:
<ProfileCard onDelete={this.deleteProfile} />
并在子组件中用作道具:
<img
src={"http://127.0.0.1:8000" + user.photo}
className="br-100 h3 w3 dib"
alt="profile pic"
onDoubleClick={() => this.props.onDelete(user.id)}
/>
答案 1 :(得分:1)
Dim EmployeeID As Integer = DirectCast(cbxEmployee.SelectedValue, EmployeeListItem).EID
在注释中是正确的。您不需要-也不需要-直接调用@estus
,但是您可以从所有者组件中调用函数。
首先,我们创建一个用于获取配置文件的新功能。仍然可以在componentDidMount
中调用它。
componentDidMount
然后我们将此功能作为fetchProfile() {
fetch('http://127.0.0.1:8000/get_profile/')
.then(response => response.json())
.then(res => this.setState({ data: res }));
}
componentDidMount() {
this.fetchProfile()
}
传递到prop
<ProfileCard />
最后,我们在<ProfileCard data={ this.state.data } onProfileDelete={ () => this.fetchProfile() } />
中删除了个人资料后,将其称为prop
。
ProfileCard