首页 > 解决方案 > 如何在 React 中为每个用户输入文本?

问题描述

在 Instagram 克隆项目中,我为每个用户创建了评论框,提交评论可以正常工作,但是输入文本会显示所有用户的文本。以下是所需的代码。

主页.js

    const [data, setData] = useState([])
    const [userProfile, setUserProfile] = useState(null)
    const {state, dispatch} = useContext(UserContext)

    /* Comment function */
    const makeComment = (text,postId)=>{
        fetch('/comment',{
            method:"put",
            headers:{
                "Content-Type":"application/json",
                "Authorization":"Bearer "+localStorage.getItem("jwt")
            },
            body:JSON.stringify({
                postId,
                text
            })
        }).then(res=>res.json())
        .then(result=>{
            console.log(result)
            const newData = data.map(item=>{
              if(item._id==result._id){
                  return {...item,comments: result.comments}
              }else{
                  return item
              }
           })
          setData(newData)
        }).catch(err=>{
            console.log(err)
        })
  }

return (
    <div className="home" >
    {
        data.map(item => {
            return (
                <div className="card home-card" key={item._id}>
                 <div className="profile-card">
                 
                 /* Profile Image */
                 <img style={{width: '50px', height:'50px', borderRadius:'80px'}} 
                            src={item.postedBy.image} />
                 <span style={{display:'flex', flexWrap:'wrap', width:'85%'}}>
                 
                 /* Profile Link */
                 <h5><Link to={item.postedBy._id !== state._id ? "/profile/"+item.postedBy._id : "/profile" } > {item.postedBy.name} </Link></h5>
                 </span>
                </div>
                
               /* Post Image */
               <div className="card-image">
           <img style={{width: '100%', height:'260px'}} src={item.photo} alt=""/>
                            </div>
                            <hr/>
           
           /* Like Button */
           <div className="like-section">
               {   item.likes.includes(state._id) ? 
               <FavoriteIcon className="like-heart" style={{ fontSize: 25 }} onClick={()=>{unlikePost(item._id)}} /> :
               <FavoriteBorderIcon className="unlike-heart" style={{ fontSize: 25 }} onClick={()=>{likePost(item._id)}} /> 
                 }

                 <h6>{item.likes.length}</h6>
                </div>
                <br/>
                 /* Comments Section */
                 <div className="card-content">
                                <h6><b>{item.title}</b></h6>
                                <p>{item.body}</p>
                                {
                                    item.comments.map(record => {
                                        return (
                                        <>    
                                        <h6 key={record._id}><b className="posted-by">{record.postedBy.name}</b>{record.text}</h6>
                                        </>
                                        
                                        )
                                    })
                                }

                      {

                      /* Comment Box  */
                      <form onSubmit={(e) => {
                            e.preventDefault();
                            makeComment(e.target[0].value, item._id)
                            setNewText("")
                       }}>
                                        
                     <input type="text" value={newtext} onChange={onChange} placeholder="add a comment" />
                     <button type="submit" disabled={!newtext}>Post</button>
                                    </form>
                                } 
                                
                                 
                            </div>
                </div>
            )
        })
    }
</div>
);
};

export default Home;  

在特定评论框中键入评论时,仅应聚焦并显示文本,但显示所有其他评论

下面是图片参考

在此处输入图像描述

上图您可以在两个评论框中看到输入时显示的“Hello”文本

在此处输入图像描述

在这里您可以看到“Hello”文本已正确提交到该特定 ID

那么,有什么合适的解决方案吗?

标签: javascriptreactjs

解决方案


那是因为您为每个评论框使用相同的状态。为了克服这个问题,您需要创建与用户一样多的状态。您可以通过使用数组进行评论轻松做到这一点

const [newText, setNewText] = useState([])

data.map((item, index) => (
...
<input value={newText[index]} onChange={(e) => setNewText(replaceByIndex(newText, index, e.target.value))} />
...
)

仅供参考,这里的replaceByIndex功能:

const replaceByIndex = (originArray, index, newItem) => 
    originArray.map((item, i) => i === index ? newItem: item)

对代码的其他增强:

  • 性能增强:使用useCallbackreact hook 定义函数组件中的函数。
  • 使用有意义的命名约定。很难理解数据和项目的含义......

推荐阅读