我有一个带有侧面板和主面板的网页。主面板是聊天屏幕。我那里有以下代码。
const MainPanel = (({ chatList }) => {
const [userChat, setUserChat] = useState('');
const [chatArray, setChatArray] = useState([]);
function handleSubmit(e) {
e.preventDefault();
// Some UI login here
postChatEntry(newMessage);
}
async function postChatEntry(message) {
const request = new Request("/chat", {
method: "POST",
body: JSON.stringify({ message: message.chatEntry })
});
const response = await fetch(request);
const jsonResponse = await response.json();
if (jsonResponse) {
chatArray.push(jsonResponse.reply);
const deepCopy = [...chatArray]
setChatArray(deepCopy);
}
}
return (
<section>
<div>
{chatArray.map((message) => {
<ChatBubble chat={message} key={message.id} />
})}
</div>
<form id="chatForm" onSubmit={handleSubmit}>
<input
placeholder='Type your message here...'
value={userChat}
onChange={(e) => setUserChat(e.target.value)}></input>
<button>Post</button>
</form>
</section>
)
})
现在,在我的侧面板中,我有用于清除聊天和加载历史记录的按钮。当我点击这些按钮时,我正在MainPanel 中的聊天部分进行更新。 在我的侧面板中,我有以下内容。
const SidePanel = (({ setChatList }) => {
function loadHistory(e) {
e.preventDefault();
fetch('/history').then((res) => res.json()).then((data) => {
const list = parseResponse(data)
setChatList(list);
});
}
return (
<div>
<ul>
<li>
<a onClick={loadHistory}>Clear Chat</span></a>
</li>
</ul>
</div>
)
})
在我的应用程序(SidePanel 和 MainPanel 的父级)中,我有以下内容:
function App() {
const [chatList, setChatList] = useState([]);
return (
<div className="col-auto col-md-3 col-xl-2 px-sm-2 px-0 bg-dark">
<div className="d-flex flex-column align-items-center">
<SidePanel setChatList={setChatList} />
</div>
<div className="col py-3 h-100">
<MainPanel chatList={chatList} />
</div>
</div>
);
}
从上面的代码中,我在主面板中有一个状态(chatArray),我可以在每次进行 API 调用时使用它来更新 dom。但是,当我从侧面板获取刷新值时,我无法在主面板中更新它。 我对 React 很陌生(一周前开始学习)。任何建议都会有所帮助。
我尝试使用在 SidePanel 中更新并通过应用程序传递到 MainPanel 的相同状态(chatList),而不是在 MainPanel 中拥有单独的状态(chatArray)。这不起作用 - 通过这种方法,侧面板中的值现在在主面板中刷新。但 MainPanel 内的 API 响应不会反映出来。
请强制组件 MainPanel 在组件 SidePanel 中每次运行 loadHistory 事件时呈现。
目前您已将 chatList 传递到 MainPanel,但它尚未在那里呈现。它必须在组件 MainPanel 中呈现。不仅如此,每当您单击“清除聊天”时,MainPanel 组件都必须重新呈现聊天历史记录。这两个功能可以通过以下方式实现。
a) 使用 key 强制在每次单击“清除聊天”时呈现 MainPanel。要了解更多信息,请参阅文档 使用密钥重置状态
<div className="col py-3 h-100">
<MainPanel key={Math.random()} chatList={chatList} />
</div>
b) 请在MainPanel中为chatList添加单独的渲染逻辑,如下所示。
{chatArray.length == 0 &&
chatList.map((message, i) => (
<Fragment key={i}>
<label>{message}</label>
<br />
</Fragment>
))}
修改后的代码的完整列表和测试结果
请注意 API 调用和问题中未包含源的组件已被适当替换 要了解工作版本的完整性,请在此处进行演示。
import { Fragment, useState } from 'react';
export default function App() {
const [chatList, setChatList] = useState([]);
return (
<div className="col-auto col-md-3 col-xl-2 px-sm-2 px-0 bg-dark">
<div className="d-flex flex-column align-items-center">
<SidePanel setChatList={setChatList} />
</div>
<div className="col py-3 h-100">
<MainPanel key={Math.random()} chatList={chatList} />
</div>
</div>
);
}
const MainPanel = ({ chatList }) => {
const [userChat, setUserChat] = useState('');
const [chatArray, setChatArray] = useState([]);
function handleSubmit(e) {
e.preventDefault();
// Some UI login here
// postChatEntry(newMessage); // commented for the MRE
postChatEntry(userChat); // added for the MRE
}
async function postChatEntry(message) {
// const request = new Request('/chat', {
// method: 'POST',
// body: JSON.stringify({ message: message.chatEntry }),
// });
// const response = await fetch(request);
// const jsonResponse = await response.json();
// if (jsonResponse) {
//chatArray.push(jsonResponse.reply); //
const deepCopy = [...chatArray, message];
setChatArray(deepCopy);
setUserChat('');
// }
}
return (
<section>
<div>
{chatArray.length == 0 &&
chatList.map((message, i) => (
<Fragment key={i}>
<label>{message}</label>
<br />
</Fragment>
))}
{chatArray.map((message, i) => (
<Fragment key={i}>
<label>{message}</label>
<br />
</Fragment>
))}
</div>
<form id="chatForm" onSubmit={handleSubmit}>
<input
placeholder="Type your message here..."
value={userChat}
onChange={(e) => setUserChat(e.target.value)}
></input>
<button>Post</button>
</form>
</section>
);
};
const SidePanel = ({ setChatList }) => {
function loadHistory(e) {
e.preventDefault();
// fetch('/history')
// .then((res) => res.json())
// .then((data) => {
// const list = parseResponse(data);
// setChatList(list);
// });
setChatList(['chat-1', 'chat-2', 'chat-3']);
}
return (
<div>
<ul>
<li>
<a onClick={loadHistory}>Clear Chat</a>
</li>
</ul>
</div>
);
};
测试结果
加载应用程序时
在新聊天中
从聊天记录加载后