代码之家  ›  专栏  ›  技术社区  ›  Davis Jones

将React上下文变量作为道具传递,而不是直接在功能组件中使用

  •  0
  • Davis Jones  · 技术社区  · 4 年前

    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>
      );
    };

    问题

    1. 为什么,当 alerts AlertTable 组件--重新渲染?重新呈现是否应该由所使用的变量的更改触发
    2. 直接在UI组件中使用上下文变量(例如。 PersonalAlerts

    事先谢谢你的帮助。

    0 回复  |  直到 4 年前