我试图从redux store中获取最新的历史值,以传递有效负载。问题是,每当我提交一个查询时,历史记录都会被更新,并在return()中使用map()循环,它显示的是最新的值,但在submitQuery()中的// CONSOLE HERE,它一直显示旧的值。
export default function Chat() {
const dispatch = useDispatch();
const { customInstructionId, chatId } = useParams()
const { history } = useSelector((state) => state.customData)
const [query, setQuery] = useState('');
const [loading, setLoading] = useState(false)
const handleSubmitQuery = async () => {
if(!query || query === "" || query === null) {
return notification("Query can't be empty.", "error")
}
setLoading(true)
const data = { id: Math.random(), role: 'user', content: query }
setQuery("")
dispatch(addData(data))
const config = { query: [...history, data], key: customInstructionId }
try {
const response = await fetch("http://localhost:8000/api/query/chat", {
method: "post",
headers: {
Accept: "application/json, text/plain, */*",
"Content-Type": "application/json",
Authorization: `Bearer ${token}`
},
body: JSON.stringify(config),
});
if (!response.ok || !response.body) {
throw response.statusText;
}
const reader = response.body.getReader();
const decoder = new TextDecoder();
const loopRunner = true;
let str = ""
let count = 0
const resId = Math.random()
setLoading(false);
/* eslint-disable no-await-in-loop */
while (loopRunner) {
const { value, done } = await reader.read();
if (done) {
// CONSOLE HERE
handleSaveHistory()
break;
}
const decodedChunk = decoder.decode(value, { stream: true });
if(value[0] === 10){
str += "\n"
} else {
str += decodedChunk
}
if(count === 0){
dispatch(addData({ id: resId, role: 'assistant', content: str }))
} else {
dispatch(updateData({ id: resId, content: str }))
}
count += 1
}
// CONSOLE HERE
} catch (err) {
console.error(err, "err");
} finally {
setLoading(false);
}
}
const handleSaveHistory = async () => {
// CONSOLE HERE
const config = saveHistory({ history, customInstructionId, chatId }, token)
axios(config)
.then((response) => {
console.log(response.data)
})
.catch((error) => {
console.log(error)
notification(`Unable to save the history.`, "error")
})
}
const handleKeyDown = (event) => {
if (event.key === 'Enter') {
handleSubmitQuery();
}
};
return (
<Page title="Query" sx={{ height: '100%' }}>
<Container sx={{ height: '100%' }}>
<Box sx={{ display: 'flex', flexDirection: 'column', justifyContent: 'space-between', height: '100%' }}>
<Box sx={{ overflowY: 'scroll', height: '70vh'}}>
{(history && history.length > 0) ? history.map((item) =>
<Card key={item.id} sx={{ marginBottom: '1rem' }}>
<Typography sx={{ padding: '1rem', backgroundColor: item.role === 'user' ? '#f8eff0' : '#edeff1' }}>
<div dangerouslySetInnerHTML={{ __html: item.content.replace(/\n/g, '<br />') }} />
</Typography>
</Card>
) :
<Card sx={{ marginBottom: '1rem' }}>
<Typography sx={{ padding: '1rem', backgroundColor: '#edeff1' }}>Hi! How can I assist you today?</Typography>
</Card>
}
{loading && loading === true &&
<Card sx={{ marginBottom: '1rem' }}>
<Typography sx={{ padding: '1rem', backgroundColor: '#edeff1' }}>
<Skeleton variant="text" sx={{ fontSize: '1rem' }} />
</Typography>
</Card>
}
</Box>
</Box>
</Container>
</Page>
);
}
Redux商店:
export const counterSlice = createSlice({
name: "customData",
initialState: {
history: [],
boolean: true,
string: ""
},
reducers: {
addData: (state, action) => {
state.history.push(action.payload)
},
updateData: (state, action) => {
state.history = state.history.map(data => {
if (data.id === action.payload.id) {
return {
...data,
content: action.payload.content
};
}
return data;
});
},
removeData: (state, action) => {
state.history = state.history.filter(data => data.id !== action.payload)
},
recentData: (state, action) => {
state.history = action.payload
},
clearData: (state) => {
state.history = []
}
}
});
export const { addData, updateData, removeData, clearData, recentData } = counterSlice.actions;
export default counterSlice.reducer;
注意:这不是完整的代码,只是显示了问题的上下文。如果有人知道为什么会发生这种情况。
在下面的图片中,历史记录确实是用dispatch()更新的,我可以在UI中看到它(就像在chatgpt中一样,它是逐字逐句地更新的)。当整个响应完成后,我将执行saveHistory函数,但在该函数中,它不接受最近的问题/答案。
历史(UI中):
- ABC
- def
- ghi
- jkl
历史记录(在saveHistory函数中): - ABC
- def
**UPDATE:**问题是在提交函数中调用保存函数。下面解决了这个问题,但我知道这不是一个好的做法。
useEffect(() => {
if(ready === true) {
handleSaveHistory()
setReady(false)
}
}, [ready]);
1条答案
按热度按时间sf6xfgos1#
异步工作需要在组件外部使用
createAsyncThunk
完成。以下内容应该放在你的Redux商店中:问题是你的钩子
handleSaveHistory
函数关闭了旧版本的数据。您有async
函数,这些函数在先前呈现的组件版本中执行。初始状态:
下一个状态:
现在
fetch
返回到 * 旧的、死的Chat1
组件 * 中下一个状态: