給定以下表單,每當提交表單時,我都需要在無需重繪 頁面的情況下列出/呈現新帖子。
const PostCreate = () => {
const [title, setTitle] = useState('');
const onSubmit = async (event) => {
event.preventDefault();
await axios.post(`http://${posts_host}/posts/create`, {title}).catch(error => {
console.log(error)
})
setTitle('');
};
return (<div>
<form onSubmit={onSubmit}>
<div className="form-group">
<label>Title</label>
<input value={title} onChange={event => setTitle(event.target.value)}
className="form-control "/>
</div>
<button className="btn btn-primary">Submit</button>
</form>
</div>)
}
export default PostCreate;
我嘗試添加this.forceUpdate()and this.setState(this.state),但都不起作用,我仍然需要重繪 頁面才能顯示新帖子。
以下是帖子的呈現方式:
const PostList = () => {
const [posts, setPosts] = useState({});
const fetchPosts = async () => {
await axios.get(`http://${queries_host}/posts`).then(response => {
setPosts(response.data);
}).catch(error => {
console.log(error)
});
};
useEffect(() => {
fetchPosts();
}, []);
const renderedPosts = Object.values(posts).map(post => {
return <div className="card"
style={{width: '30%', marginBottom: '20px'}}
key={post.id}>
<div className="card-body">
<h3>{post.title}</h3>
<CommentList comments={post.comments}></CommentList>
<CommentCreate postId={post.id}></CommentCreate>
</div>
</div>
});
return <div>
{renderedPosts}
</div>;
}
export default PostList;
這App.js看起來像
const App = () => {
return <div>
<h1>Create Post</h1>
<PostCreate></PostCreate>
<hr/>
<h1>Posts</h1>
<PostList></PostList>
</div>;
};
export default App;
并最終使用:
ReactDOM.render(
<App></App>,
document.getElementById('root')
)
uj5u.com熱心網友回復:
在您的PostList, useEffect 在您首次加載組件時呼叫一次,因此當您創建新帖子時,它不會被重新渲染
您應該將您的fetchPost邏輯帶到您的 App 組件中,并將功能道具添加onPostCreated到PostCreate組件中,在您完成創建新帖子后觸發它
代碼應該是:
const App = () => {
const [posts, setPosts] = useState({});
const fetchPosts = async () => {
await axios.get(`http://${queries_host}/posts`).then(response => {
setPosts(response.data);
}).catch(error => {
console.log(error)
});
};
useEffect(() => {
fetchPosts();
}, []);
return <div>
<h1>Create Post</h1>
<PostCreate onCreatePost={() => fetchPost()}></PostCreate>
<hr/>
<h1>Posts</h1>
<PostList posts={posts}></PostList>
</div>;
};
export default App;
const PostList = ({ posts }) => {
const renderedPosts = Object.values(posts).map(post => {
return <div className="card"
style={{width: '30%', marginBottom: '20px'}}
key={post.id}>
<div className="card-body">
<h3>{post.title}</h3>
<CommentList comments={post.comments}></CommentList>
<CommentCreate postId={post.id}></CommentCreate>
</div>
</div>
});
return <div>
{renderedPosts}
</div>;
}
export default PostList;
const PostCreate = ({ onCreatePost }) => {
const [title, setTitle] = useState('');
const onSubmit = async (event) => {
event.preventDefault();
await axios.post(`http://${posts_host}/posts/create`, {title}).catch(error => {
console.log(error)
})
onCreatePost && onCreatePost();
setTitle('');
};
return (<div>
<form onSubmit={onSubmit}>
<div className="form-group">
<label>Title</label>
<input value={title} onChange={event => setTitle(event.target.value)}
className="form-control "/>
</div>
<button className="btn btn-primary">Submit</button>
</form>
</div>)
}
export default PostCreate;
uj5u.com熱心網友回復:
我認為您遇到的問題不在您顯示的代碼中。在您更改其狀態以及 forceUpdate() 之后,該組件確實在重新渲染。我假設您嘗試顯示的帖子取自您發布到的同一 API。即使正在重新呈現此組件,也不會再次呼叫將資料提供給呈現它的組件的 GET 請求,因此資料不會更新。您需要重新獲取它。這可以通過許多不同的方式(useEffect()、回呼、reactQuery refetch)來完成,具體取決于您的代碼的其余部分。我需要呈現資料的組件和 API 呼叫來進一步幫助您。
另一件你沒有問但很好的做法。在您的 PostCreate 組件中,您不需要管理表單中欄位的狀態,因為它已經為您完成了。只需為您的輸入命名并使用表單資料。我在下面給出了一個例子。
import { useState } from "react";
const PostCreate = () => {
const onSubmit = async (event) => {
event.preventDefault();
console.log(event.target.elements.title.value);
};
return (
<div>
<form onSubmit={onSubmit}>
<div className="form-group">
<label>Title</label>
<input name="title" className="form-control" />
</div>
<button className="btn btn-primary">Submit</button>
</form>
</div>
);
};
export default PostCreate;
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/515974.html
標籤:反应形式提交时
