使用react钩子操作数组

时间:2019-03-25 15:08:13

标签: reactjs react-hooks

说我有一个获取数组的组件,并且我想做一些逻辑:

const MyComponent = ({ myArray = [] }) => {
  console.log("infinite rendering");
  const [prop, setProp] = useState([])
  useEffect(() => {
    setProp(myArray.map(x => x + 1))
  }, [myArray])

  return <div />
}

https://codesandbox.io/s/x3kq907r5z

问题是我遇到了无限循环。

我可以通过删除默认值({ myArray })并检查数组if (Array.isArray(myArray)) setProp(...)

来修复该错误。

但是我很难理解: 使用钩子对道具(数组/对象/等)进行各种操作的最佳方法是什么?

2 个答案:

答案 0 :(得分:4)

按照当前编写代码的方式,USE TADS DECLARE @NAME VARCHAR(MAX), @DOWNLOAD_PATH VARCHAR(MAX), @IMG_PATH varchar(MAX), @TIMESTAMP VARCHAR(MAX), @ObjectToken INT, @START_TIME SMALLDATETIME, @END_TIME SMALLDATETIME, @hr int SET @START_TIME = '01/01/2018' SET @END_TIME = '12/31/2018' SET @DOWNLOAD_PATH = 'D:\testfile\' DECLARE IMGPATH CURSOR FAST_FORWARD FOR SELECT FILE_NAME, FILE_PATH from ATTACHED_FILES where DATE_ADDED between @START_TIME and @END_TIME OPEN IMGPATH FETCH NEXT FROM IMGPATH INTO @NAME, @IMG_PATH WHILE @@FETCH_STATUS = 0 BEGIN SET @IMG_PATH = 'D:\TADS\TADS_SVN_WORKING_DIR\TADS_DEV2_WC'+@IMG_PATH SET @TIMESTAMP = @DOWNLOAD_PATH + @NAME PRINT @TIMESTAMP EXEC @hr = sp_OACreate 'ADODB.Stream', @ObjectToken OUTPUT IF @hr <> 0 BEGIN RAISERROR('Error %d creating object.', 16, 1, @hr) RETURN END EXEC @hr = sp_OASetProperty @ObjectToken, 'Type', 1 IF @hr <> 0 BEGIN RAISERROR('Error %d creating object.', 16, 1, @hr) RETURN END EXEC @hr = sp_OAMethod @ObjectToken, 'Open' IF @hr <> 0 BEGIN RAISERROR('Error %d creating object.', 16, 1, @hr) RETURN END EXEC @hr = sp_OAMethod @ObjectToken, 'Write', NULL, @IMG_PATH IF @hr <> 0 BEGIN RAISERROR('Error %d creating object.', 16, 1, @hr) RETURN END EXEC @hr = sp_OAMethod @ObjectToken, 'SaveToFile', NULL, @TIMESTAMP, 2 IF @hr <> 0 BEGIN RAISERROR('Error %d creating object.', 16, 1, @hr) RETURN END EXEC @hr = sp_OAMethod @ObjectToken, 'Close' IF @hr <> 0 BEGIN RAISERROR('Error %d creating object.', 16, 1, @hr) RETURN END EXEC @hr = sp_OADestroy @ObjectToken FETCH NEXT FROM IMGPATH INTO @NAME, @IMG_PATH END CLOSE IMGPATH DEALLOCATE IMGPATH 是每个渲染上空数组的不同实例。这意味着效果总是运行,因为依赖项总是在变化!

这似乎很奇怪,但是请考虑以下代码:

myArray

最简单的解决方法是将后备逻辑移入效果:

const a = [];
const b = [];
console.log(a === b); // false

或者确保始终使用相同的空数组作为默认值:

const MyComponent = ({ myArray }) => {
  console.log("infinite rendering");
  const [prop, setProp] = useState([]);
  useEffect(
    () => {
      setProp(myArray ? myArray.map(x => x + 1) : []);
    },
    [myArray]
  );

  return <div />;
};

答案 1 :(得分:0)

  

但是我很难理解:用钩子对道具(数组/对象/等)进行任何形式操纵的最佳方法是什么?

当您尝试操纵局部状态值而不是道具时,钩子很棒。您可以使用useState()定义状态,并使用useEffect()或其他事件处理程序来更新值。

在组件的外部处更改道具,这会触发功能组件重新执行。因此,要回答您的问题:您不要用钩子操纵道具。最好的办法是在使用useMemo()更改道具时阻止渲染,但这是一个不同的话题。

话虽如此,您的示例可以变成:

matching_label_rows = Label.objects.filter(input)
matching_main_data_rows = matching_label_rows.mainMatch_set.????