Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/404.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript React从父道具克隆对象在重新渲染时不断更新_Javascript_Arrays_Reactjs_React Props - Fatal编程技术网

Javascript React从父道具克隆对象在重新渲染时不断更新

Javascript React从父道具克隆对象在重新渲染时不断更新,javascript,arrays,reactjs,react-props,Javascript,Arrays,Reactjs,React Props,我不确定这是怎么解决的。我们从API中获得一个对象数组,并使用它在视图中创建数据。同时,在子组件(过滤器)中,我希望映射数据中的一个字段以创建过滤器类别。过滤器将使用参数从API中调用新数据,并返回该数据并更新PROP(我认为这是问题所在,因为这会使用过滤后的数据重新编辑子组件以再次设置类别) 我认为将数组放入useEffect会阻止它被更新 以下是我的过滤器组件中的当前tsx: const ExclusiveOffersFilters = (props: ExclusiveOffersFilt

我不确定这是怎么解决的。我们从API中获得一个对象数组,并使用它在视图中创建数据。同时,在子组件(过滤器)中,我希望映射数据中的一个字段以创建过滤器类别。过滤器将使用参数从API中调用新数据,并返回该数据并更新PROP(我认为这是问题所在,因为这会使用过滤后的数据重新编辑子组件以再次设置类别)

我认为将数组放入useEffect会阻止它被更新

以下是我的过滤器组件中的当前tsx:

const ExclusiveOffersFilters = (props: ExclusiveOffersFiltersProps): JSX.Element => {
  const newFilters = JSON.parse(JSON.stringify(props.options)); // copy the object from props
  let filterOffers;

  useEffect(() => {
    filterOffers = newFilters.map((item: any) => {
      return { value: item.offerType, display: item.offerType };
    });
    console.log('filterOffers: ', filterOffers); // succesfully logs the filtered items. 
  }, []);

  return (
    <tr>
      <th>
        <Filter
          options={filterOffers} // here filterOffers is undefined
          alignRight={props.alignRight}
          handleClick={props.handleFilterChange}
          multiSelect={props.multiSelect}
          selectedItems={props.selectedItems}
        />
      </th>
    </tr>
  );
};
如果我们在offerType=Motoring上进行筛选,那么我们将再次调用api,并将Motoring作为我们的筛选器。这将只返回来自上述数据的1条记录,但现在我们的筛选器得到更新,并且只显示1个Motoring的筛选器类别

请参阅应用程序附带的示例

我在这里转储了大部分文件:带有示例数据。我不知道这有多大帮助,当有这么多依赖项时,很难做出一个有效的示例

父index.tsx处理所有ajax api调用,并将数据传递到props。ExclusiveOffersFilters.tsx接收并更新,这是我想要停止的部分。正如@Adam在评论中指出的,我们正在努力解决这个问题,但我认为实际上家长是好的,问题出在孩子身上

我们确实希望在应用程序的其他地方应用此逻辑,因此性能会很好。我想知道我是否只需要不使用道具。选项和使用不同的道具

  • useffect
    执行异步,因此可以在渲染时取消定义
    filterOffers

  • 如果要基于其他值创建值并对其进行优化,请使用
    usemo
    hook

    const newFilters = useRef(JSON.parse(JSON.stringify(props.options))); // copy the object from props
    const filterOffers = useMemo(() => {
         filterOffers = newFilters.current.map((item: any) => {
             return { value: item.offerType, display: item.offerType };
         });
         console.log('filterOffers: ', filterOffers); // succesfully logs the filtered items. 
    }, [newFilters]);
    
  • 如果要在组件的重新渲染之间存储值,请使用
    useRef
    hook

    const newFilters = useRef(JSON.parse(JSON.stringify(props.options))); // copy the object from props
    const filterOffers = useMemo(() => {
         filterOffers = newFilters.current.map((item: any) => {
             return { value: item.offerType, display: item.offerType };
         });
         console.log('filterOffers: ', filterOffers); // succesfully logs the filtered items. 
    }, [newFilters]);
    

  • 这就是你所需要的。如果遇到性能问题,请使用
    usemo
    。如果您没有遇到性能问题,请不要做任何事情

    const ExclusiveOffersFilters = (props: ExclusiveOffersFiltersProps): JSX.Element => {
    
      const filters = props.options.map((item) => ({
        value: item.offerType, 
        display: item.offerType
      }));
    
      return (
        <tr>
          <th>
            <Filter
              options={filters}
              alignRight={props.alignRight}
              handleClick={props.handleFilterChange}
              multiSelect={props.multiSelect}
              selectedItems={props.selectedItems}
            />
          </th>
        </tr>
      );
    };
    

    除非你绝对确定你需要它,否则我再强调也不想离开
    usemo

    你为什么要使用
    useRef
    ?您是否要将
    newFilters
    作为依赖项添加到
    usemo
    newFilters
    是一个ref,永远不会更改。也许我误解了这个问题,但我的想法是在重新渲染之间保存它们。据我所知,OP希望在重新渲染之间保存原始过滤器,这就是为什么我使用
    useRef
    嘿,谢谢你,我似乎无法让它正常工作。但是您已经将filterOffers设置为常量,然后在useMemo函数中再次调用它。我已经更新了我的问题,并提供了参考资料、样本数据和屏幕截图的链接。我认为函数应该是
    const filterOffers=usemo(()=>{return filterOffers=newFilters.current.map((item:any)=>{return{value:item.offerType,display:item.offerType};});console.log('filterOffers:',filterOffers);//成功地记录过滤的项。},[newFilters])
    @lharby抱歉,但是由于这个答案将
    newFilters
    放入
    usemo
    的依赖项数组中,它清楚地表明了这个答案的不一致性。这对您没有帮助。听起来您正试图通过在父组件中应用hack来修复子组件中的问题(两个错误不能代表正确)。发布子组件的代码,我有一种感觉,问题是什么马上就会显而易见。@Adam我已经更新了我的问题,并提供了该问题的大多数文件、示例数据和屏幕截图的链接。谢谢,我会尝试一下,但我怀疑props.options会在重播时更新。@lharby它会的,但是我已经重新阅读了你的问题和两件事——首先,整个JSON.parse JSON.stringify东西都是胡说八道,其次,你试图通过向这个组件添加一个hack来修复底层组件中的一个bug。发布您所说的不断更新的较低组件的代码,并在其实际位置修复错误,而不是对该组件进行黑客攻击。好的,我将在明天获取此代码并进行更新,非常感谢您的支持input@lharby-你的密码笔现在不工作,但我几乎可以保证问题与您在
    Filter.tsx
    中使用
    splice
    push
    有关。当涉及到反应时,不要改变任何东西,状态,道具,任何东西。
     const filters = useMemo(() => props.options.map(....),[props.options]);