簡體   English   中英

我如何從我的反應 state 返回 object

[英]How do i return an object from my react state

我正在嘗試從下面的代碼中從集合中找到一個項目,以更新我的反應組件,propertState object 不是空的,它包含一個我已在控制台記錄的列表,但是當我控制台記錄從我的findProperty function 返回的值...我正在嘗試使用該值更新我的 localState,以便我的組件可以呈現正確的數據。

    const PropertyComponent = () => {
        const { propertyId } = useParams();
    
        const propertyState: IPropertiesState = useSelector(
            propertiesStateSelector
        );
    
        const[property, setProperty] = useState()
    
        const findProperty = (propertyId, properties) => {
            let propertyReturn;
            for (var i=0; i < properties.length; i++) {
                if (properties[i].propertyId === propertyId) {
                    propertyToReturn = properties[i];
                    break;
                }
            }
            setProperty(propertyReturn)
            return propertyReturn;
        }
    
        const foundProperty = findProperty(propertyId, propertyState.properties);
    
        return (<>{property.propertyName}</>)
    }

export default PropertyComponent

當您根據外部數據源查找數據和更新狀態時,您應該考慮一些事項 --useParams--

我將嘗試通過將您的代碼分成小塊來解釋解決方案

    const PropertyComponent = () => {
        const { propertyId } = useParams();

部分A:考慮useParams是一個連接到路由器的鈎子,這意味着您的組件可能是反應性的,並且每次 URL 中的參數更改時都會更改。 您的參數可能未定義或字符串取決於參數是否存在於您的 URL

const propertyState: IPropertiesState = useSelector(
            propertiesStateSelector
        );

部分B: useSelector是另一個屬性,它可以讓您的組件對與該選擇器相關的更改做出反應。 您的選擇器可能會根據您的選擇邏輯返回 undefined 或其他內容。

const[property, setProperty] = useState()

部分 C:您的 state 在第一次渲染中開始為undefined

到目前為止,我們剛剛發現了 3 段可能以未定義或未定義開頭的代碼。

const findProperty = (propertyId, properties) => {
            let propertyReturn;
            for (var i=0; i < properties.length; i++) {
                if (properties[i].propertyId === propertyId) {
                    propertyToReturn = properties[i];
                    break;
                }
            }
            setProperty(propertyReturn)
            return propertyReturn;
        }
    
        const foundProperty = findProperty(propertyId, propertyState.properties);

部分D:這是開始出現更多問題的時候,你告訴你的代碼在每次渲染中都會創建一個 function findProperty並使用 state --setProperty-- 的設置器添加一些內部依賴項。

我建議您通過簡單的步驟考慮您想要執行的操作,然后您就可以了解每段代碼屬於哪里。

讓我們細分最后一段代碼--D部分--但在步驟中,您想要:

  1. 找東西。
  2. 如果您有一個可以在哪里查找的數組和一個屬性,則應該進行查找。
  3. 結果我想通知我的組件發現了一些東西。

步驟 1 和 2 可能發生在您的組件外部定義的 function 中:

const findProperty = (propertyId, properties) => properties.find((property) => property.propertyId === propertyId)

注意:我冒昧地通過簡化您的發現 function 來修改您的代碼。

現在我們需要做最重要的一步,讓你的組件在正確的時間做出反應

const findProperty = (propertyId, properties) => properties.find((property) => property.propertyId === propertyId)

const PropertyComponent = () => {
        const { propertyId } = useParams();
    
        const propertyState: IPropertiesState = useSelector(
            propertiesStateSelector
        );
         
        const[property, setProperty] = useState({ propertyName: '' }); // I suggest to add default values to have more predictable returns in your component

        /**
         * Here is where the magic begins and we try to mix all of our values in a consistent way (thinking on the previous pieces and the potential "undefined" values) We need to tell react "do something when the data is ready", for that reason we will use an effect
         */

        useEffect(() => {
          // This effect will run every time that the dependencies --second argument-- changes, then you react afterwards.
          if(propertyId, propertyState.properties) {
              const propertyFound = findProperty(propertyId, propertyState.properties);
              if(propertyFound){ // Only if we have a result we will update our state.
                setProperty(propertyFound);
              }
          }
        }, [propertyId, propertyState.properties])
 

        return (<>{property.propertyName}</>)
    }

export default PropertyComponent

我認為這樣你的意圖可能更直接,但肯定還有其他方法可以做到這一點。 根據您的意圖,您的代碼應該有所不同,例如我有一個問題:

這個組件的目的是什么? 如果它只是為了獲取屬性,你可以做一個派生的 state ,一個更復雜的選擇器。 例如

function propertySelectorById(id) {
   return function(store) {
      const allProperties = propertiesStateSelector(store);
      const foundProperty = findProperty(id, allProperties);
      if( foundProperty ) {
         return foundProperty;
      } else {
         return null; // Or empty object, up to you
      }
   }
}

然后你可以在任何使用 useParam 的組件中使用它,或者只是創建一個簡單的 hook 例如


function usePropertySelectorHook() {
   const { propertyId } = useParams();
   const property = useSelector(propertySelectorById(propertyId));

   return property;
}

之后你可以在任何組件中使用它


functon AnyComponent() {
  const property = usePropertySelectorHook();

  return <div> Magic {property}</div>
}

注意:我沒有測試所有代碼,我直接在評論中寫了它,但我認為應該可以。

像這樣我認為有更多的方法可以解決這個問題,但現在已經足夠了,希望這對你有所幫助。

你試試這個:

const found = propertyState.properties.find(element => element.propertyId === propertyId);
setProperty(found);

而不是所有 function findProperty

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM