简体   繁体   English

为什么当道具改变时我的页面没有重新呈现? React新手用头撞墙两天

[英]Why isn't my page re-rendering when props change? React newbie beating his head against the wall for two days

I'm working on my first React app (a simple blog site) after doing a few tutorials, and I've been struggling with this issue for two days now.在完成一些教程后,我正在开发我的第一个 React 应用程序(一个简单的博客网站),我已经为这个问题苦苦挣扎了两天。 Would love some help on this one!会喜欢这方面的一些帮助!

My site lists blog posts which it pulls from the database, and I have an edit button next to a list of posts.我的网站列出了它从数据库中提取的博客文章,并且我在文章列表旁边有一个编辑按钮。 When I push the button I query the database to pull all the data for the post in question, and send it via a prop to the edit component.当我按下按钮时,我查询数据库以提取相关帖子的所有数据,并通过道具将其发送到编辑组件。

import React, {useEffect, useState} from 'react'
import BlogPostEdit from './BlogPostEdit';


const initPostToEdit = {
  post_id: 49,
  title: 'test title 2',
  sub_title: 'test sub-title',
  main_content:'test content',
  post_url:'test-url',
  page_title:'',
  meta_description:'',
  meta_keywords:''
  }

export default function BlogPostList() {
    const [posts, setPosts] = useState([]);   
    const [postToEdit, setPostToEdit] = useState(initPostToEdit);   

    const deletePost = async (id) => {
        try {
            await fetch(`http://localhost:5001/blog-edit/${id}`, {
                method: "DELETE"
            })
            setPosts(posts.filter(post => post.post_id !== id))
        } catch (error) { 
            console.error(error.message)      
        }
    }

    const editPost = async (id) => {
        try {
            const response = await fetch(`http://localhost:5001/blog-edit/${id}`, {
                method: "GET"
            })
            const newPostToEdit = await response.json();
            setPostToEdit(newPostToEdit[0]);
        } catch (error) { 
            console.error(error.message)      
        }
    }
    
    const getPosts = async () => {
        try {
            const response = await fetch("http://localhost:5001/blog-edit");
            const jsonData = await response.json();
            setPosts(jsonData);
        } catch (error) { 
            console.error(error.message)      
        }
    }
    useEffect(() => {getPosts();}, [])

  return (

    <div>
   
  <BlogPostEdit postToEdit = {postToEdit} /> 

  <h1> List of Blog Posts</h1>

  <div className="container">
          
  <table className="table table-striped">
    <thead>
      <tr>
        <th>Title</th>
        <th>Date</th>
        <th>Content</th>
        <th>Edit</th>
        <th>Delete</th>
      </tr>
    </thead>
    <tbody>
      {posts.map(post => (
              <tr key={post.post_id}>
              <td>{post.title}</td>
              <td>{post.post_date}</td>
              <td>{post.main_content.slice(0,100)}</td>
              <td>
                <button
                 className="btn btn-success"
                 onClick={ () => editPost(post.post_id)}
                 >
                Edit</button></td>
              <td>
                <button 
                className="btn btn-danger"
                onClick={() => deletePost(post.post_id)}
                >
                Delete</button></td>
              
            </tr>

      ))}  
    </tbody>
  </table>
</div>  
    </div>
  )
  
}

In the edit component, the props pass along an initial filler/dummy info which populate the edit form fine.在编辑组件中,道具传递一个初始填充/虚拟信息,这些信息可以很好地填充编辑表单。 But I can't figure out how to populate the form with info from the post I want to edit, in such a way that I can submit the form and modify the database.但是我不知道如何用我想编辑的帖子中的信息填充表单,这样我就可以提交表单并修改数据库。

import React, { useState, useEffect } from 'react'

    export default function BlogPostEdit(props) {
        const [blogValues, setBlogValues] = 
        useState(props.postToEdit);
             
        const changeHandler = e => {
         setBlogValues({...blogValues, [e.target.name]: 
         e.target.value});
        }
            
        return (
          <div>
            <h1 className='text-center mt-5'>Edit Blog Post</h1>
            <form className="mt-5" onSubmit={ onSubmitForm }>
      
              <label htmlFor="title">Blog Post Title</label>
              <input
                id="title"
                name="title"
                type="text" 
                className='form-control'
                value={ blogValues.title } 
                onChange = { changeHandler }
              />
              
              <label htmlFor="sub_title">Blog Post Sub-Title</label>
              <input
                id="sub_title"
                name="sub_title"
                type="text" 
                className='form-control'
                value={blogValues.sub_title}
                onChange = {changeHandler}
              />
      
              <label htmlFor="main_content">Blog Post Content</label>
              <input
                id="main_content"
                name="main_content"
                type="text" 
                className='form-control'
                value={blogValues.main_content}
                onChange = {changeHandler}
              />
      
              <label htmlFor="post_url">Blog Post URL</label>
              <input
                id="post_url"
                name="post_url"
                type="text" 
                className='form-control'
                value={blogValues.post_url}
                onChange = {changeHandler}
              />
      
              <label htmlFor="page_title">Blog Post Page 
              Title</label>
              <input
                id="page_title"
                name="page_title"
                type="text" 
                className='form-control'
                value={blogValues.page_title}
                onChange = {changeHandler}
              />
              <label htmlFor="meta_description">Meta 
               Description</label>
              <input
                id="meta_description"
                name="meta_description"
                type="text" 
                className='form-control'
                value={blogValues.meta_description}
                onChange = {changeHandler}
              />
      
              <label htmlFor="meta_keywords">Meta Keywords</label>
              <input
                id="meta_keywords"
                name="meta_keywords"
                type="text" 
                className='form-control'
                value={blogValues.meta_keywords}
                onChange = {changeHandler}
              />
              <button className='btn btn-success'>Submit 
              Edits</button>
            </form>
          </div>
        )
}

        

If I console.log the props in the BlogPostEdit function, I can see them changing to reflect me choosing different posts to edit.如果我 console.log BlogPostEdit function 中的道具,我可以看到它们发生变化以反映我选择不同的帖子进行编辑。 The only way I can get this to reflect in the edit form is by using something like value = {props.propsToEdit.title} in the form.我能让它反映在编辑表单中的唯一方法是在表单中使用类似 value = {props.propsToEdit.title} 的东西。 But when I do this, whenever I try to make edits to the form it immediately reverts to the original title.但是,当我这样做时,每当我尝试对表单进行编辑时,它都会立即恢复为原始标题。

When I try to use the useState update function (setBlogValues), to reflect the new prop values, I get errors saying too many renders are happening.当我尝试使用 useState 更新 function (setBlogValues) 来反映新的 prop 值时,我收到错误消息说正在发生太多渲染。

I hope this makes sense.我希望这是有道理的。 Again, any help appreciated!再次感谢任何帮助!

You should not write the props.postToEdit on the useState hook, simply execute the function and pass on the post id you would like to edit.您不应该在 useState 挂钩上编写 props.postToEdit,只需执行 function 并传递您要编辑的帖子 ID。 You're currently using the state for the function and for manipulating your state, this wont simply work.您当前正在将 state 用于 function 并操纵您的 state,这不会简单地起作用。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM