ReactJS - 如何在将数据发布到数据库后重新渲染功能组件

Posted

技术标签:

【中文标题】ReactJS - 如何在将数据发布到数据库后重新渲染功能组件【英文标题】:ReactJS - How to re-render functional component after POST data to database 【发布时间】:2021-07-11 03:45:58 【问题描述】:

我正在构建一个博客应用程序。这个应用程序的前端是用 ReactJS 构建的,后端是用 Python(Django 框架)构建的。前端和后端通过 Django REST API 框架连接。

这篇文章在 ReactJS 前端。

我正在使用功能组件。有一个“BlogList”组件,其中将显示从 API 端点获取的所有博客。我创建了一个“BlogForm”组件,我必须在其中输入 2 个字段:“标题”和“内容”来创建博客文章。我在“BlogList”组件中导入了“BlogForm”组件以在同一页面上显示它。 Please see this image to get a good understanding

当我在“BlogForm”组件中输入“标题”和“内容”并单击“提交”按钮时,数据使用 API 调用保存在数据库中。但当时添加的数据并未显示在“BlogList”组件中。我必须刷新页面才能在博客列表中看到新的博文。

社区中的任何人都可以帮助我解决单击“提交”按钮时如何立即查看添加的博客文章的问题吗?

代码如下。

BlogList.js

import BlogForm from './BlogForm'

const BlogList = (url) => 

    
    const [blogs, setBlogs] = useState([])

    useEffect(() => 
        
        async function fetchBlogData() 
            
            const url = requests.blogList

            const request = await axios.get(url)

            setBlogs(request.data)
            return request
        
        fetchBlogData()
    , [url])

    return (
        <Wrapper>
            <BlogWrapper className="blog">

                // Blog Form Component Added
                <BlogForm />

                <div className="blog__header">
                    <h1 className="blog__header--title">
                        Information
                    </h1>
                </div>
                <hr className="blog__divider"/>
                <div className="blog__list">
                    <ul>
                        <li className="blog__item">
                             blogs.map( (blog) => (
                                <div className="blog__item--container" key= blog.id >
                                    <h1 className="blog__item--title">
                                        <a className="blog__item--title blog__item--title--link" href=`/blog/$ blog.id `>
                                             blog.title 
                                        </a>
                                    </h1>
                                    <small className="blog__item--date"> blog.date_published </small>
                                    <p className="blog__item--content"> blog.content </p>
                                </div>
                            ) ) 
                        </li>
                    </ul>
                </div>
            </BlogWrapper>
        </Wrapper>
    )


export default BlogList

BlogForm.js

const BlogForm = () => 

    const [inputValues, setInputValues] = useState(
        title : '',
        content : ''
    )

    const handleSubmit = async (event) => 
        event.preventDefault()
        setInputValues( ...inputValues )

        const  title, content  = inputValues
        const blogPost =  title, content 

        const url = requests.blogCreate
        const response = await axios.post(url, blogPost)
        return response
    

    const handleChange = (name) => (event) => 
        setInputValues( ...inputValues, [name] : event.target.value )
    

    return (
        <div>
            <form onSubmit= handleSubmit >
                <input type="text" name="title" placeholder="Title" required value= inputValues.title  onChange= handleChange('title') />
                <input type="text" name="content" placeholder="Content" required value= inputValues.content  onChange= handleChange('content') />
                <button type="submit">Submit</button>
            </form>
        </div>
    )


export default BlogForm

更新

在得到 DrewReese 的答复后,我更新了代码,但在尝试添加新博客文章时出现错误。它显示undefined

【问题讨论】:

你能演示一下这两个组件是如何相互关联的,它们是如何呈现的吗?据我所知,您只需更新BlogList 中的props 对象(您将其命名为url),它应该会重新渲染并触发效果回调。 @DrewReese:我只是在BlogList 组件中导入BlogForm 组件。 您需要 BlogList 中的某种回调函数,将其作为道具传递给 BlogForm。 对不起,如果不清楚,我指的是响应正文,而不是请求状态,换句话说,你在代码中得到了什么。 GET 请求中的 console.log(request.data) 和 POST 请求中的 console.log(response) 之类的东西。 我得到了解决方案。它应该是 POST 请求中的 response.data。非常感谢@DrewReese 【参考方案1】:

BlogList 具有您想要从子组件BlogForm 更新的状态。您可以从父级向子级传递回调,以便BlogForm 调用更新的帖子。

博客列表

const BlogList = (props) => 
    const [blogs, setBlogs] = useState([]);

    useEffect(() => 
        async function fetchBlogData() 
            const url = requests.blogList;
            const request = await axios.get(url);
            setBlogs(request.data);
        
        fetchBlogData();
    , [props]);

    // (1) Define a callback to update state
    const addNewPost = post => setBlogs(posts => [...posts, post]);

    return (
        <Wrapper>
            <BlogWrapper className="blog">

                // Blog Form Component Added
                <BlogForm addNewPost=addNewPost /> // <-- (2) pass callback

                ...
            </BlogWrapper>
        </Wrapper>
    );

博客表单

const BlogForm = ( addNewPost ) =>  // <-- (3) destructure callback

    const [inputValues, setInputValues] = useState(
        title : '',
        content : ''
    )

    const handleSubmit = async (event) => 
        event.preventDefault()
        setInputValues( ...inputValues );

        const  title, content  = inputValues;
        const blogPost =  title, content ;

        const url = requests.blogCreate;
        const response = await axios.post(url, blogPost);
        addNewPost(response.data); // <-- (4) call callback with new post data
    

    ...

    return (
        ...
    );

【讨论】:

感谢您的代码解释。当我单击“提交”按钮时,我在页面中收到undefined 结果。你能帮我解决这个问题吗? @JeetZawab-UlHakimKhondker 当然可以,但是您能指出未定义值所在的特定代码行吗? 我在您的 gmail 中向您发送了一封电子邮件。你能在那里检查并回复吗?演示会更容易。 @JeetZawab-UlHakimKhondker 我只是想问您是否可以将我们指向您所看到的未定义值的特定代码行。如果有一个堆栈跟踪伴随错误消息,那就太好了。如果可以,请使用这些新的详细信息更新您的问题。

以上是关于ReactJS - 如何在将数据发布到数据库后重新渲染功能组件的主要内容,如果未能解决你的问题,请参考以下文章

如何在状态更改(父)reactjs时重新渲染子组件

来自 ReactJS 的多附加 Laravel

gsutil rsync 尝试在将源迁移到新存储后重新上传所有内容

如何以 Node JS 作为后端将 Mysql 数据获取并显示到 ReactJS 前端?

JTable 不会在将数据插入 mysql 时重新绘制/刷新

删除突变后不重新获取查询(Apollo Graphql & Nextjs)