useState()
setState()
方法),使用此变量的函数组件之一不会更新。这个变量应该直接在功能组件中使用,还是作为父功能组件的道具传递?
预期行为
用户单击一个按钮,触发删除他们设置的通知之一。然后,UI从UI中显示的表行中删除该通知。当没有通知时,会向用户显示添加通知的选项。然后,当用户添加通知时,它将作为表行显示在UI中。
观察到的行为
用户可以删除通知(这会立即反映在表中),但是当删除所有通知并且用户尝试添加一个通知时,通过使用
方法,但这不会导致函数组件通过
useContext()
方法来更新UI。
相关代码段
上下文组件实例化
alert
变量,并使用Reducer函数对其进行更新
import React, { createContext, useState } from 'react'
import { sampleUser } from '../SampleData'
export const SettingsContext = createContext();
const SettingsContextProvider = props => {
// Instantiates alerts array (via sample data), and establishes the setAlert update method
const [alerts, setAlerts] = useState(importedSampleUser.withoutAlert);
...
/** Reducer function that handles all notification modifications.
* @param {type} string Add, delete, personal, or organizational.
* @param {obj} obj Object containing the details needed to complete the action on the backend.
*/
const updateAlerts = (type, obj) => {
switch (type) {
// Creates an empty array if notificaitons have all been deleted
case "add notification":
if (!alerts.length) {
setAlerts([]);
};
let newAlertArray = alerts;
newAlertArray.push({
id: obj.id,
type: "Birthday",
group: obj.group,
hoursPrior: obj.hoursPrior
});
// Updates the variable consumed by the UI Component
setAlerts(newAlertArray);
break;
case "delete notification":
let withoutAlert = alerts;
withoutAlert = withoutAlert.filter(alert => alert.id !== obj.id);
setAlerts(withoutAlert);
break;
default:
console.log("Oops! No more alert update types available.");
return;
}
}
UI组件生成布局
const PersonalAlerts = () => {
// Holds basic layout
return (
<div>
<h5>Your Alerts</h5>
{/* Displays a table with a list of notifications the user has set */}
<AlertTable />
</div>
);
子UI组件基于
警觉的
从上下文消耗的变量
const AlertTable = () => {
// Consumes the alerts state from the Context Component
const { alerts, updateAlerts } = useContext(SettingsContext);
// Handles personal alert delete requests.
const deleteAlert = (e, type, id) => {
e.preventDefault();
// Dispatches action to Settings Context
updateAlerts("delete personal", { id });
};
// Builds an element in the table for each alert the user has set.
let tableElements = alerts.map(alert => {
...
return (
<tr key={alert.id}>
{/* Builds alert row for each alert in array received from Context */}
<td>{alert.type}</td>
</tr>
);
});
// Builds a table row to display if there are no personal alerts to display.
const noAlerts = (
<tr>
<td onClick={() => triggerAddNotificationUI()}>Add a notificaiton</td>
</tr>
);
};
问题
-
为什么,当
alerts
AlertTable
组件--重新渲染?重新呈现是否应该由所使用的变量的更改触发
-
直接在UI组件中使用上下文变量(例如。
PersonalAlerts
事先谢谢你的帮助。