说我有一个获取数组的组件,并且我想做一些逻辑:
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(...)
但是我很难理解: 使用钩子对道具(数组/对象/等)进行各种操作的最佳方法是什么?
答案 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.????