useEffect 中有一个 setState 并且是 console.logging null
useEffect has a setState in it and is console.logging null
我会尽量用最好的方式表达这个...
当我通过道具将函数发送到 child,然后再次将其发送到另一个 child 时,然后使用点击在 'grandparent' 函数中激活它。当我 console.log 在 grandparent 中的原始函数中 console.log 是一个状态时,它打印未定义,但是当我在那个 grandparent 中并尝试激活该函数时,它将正确记录状态。如果有人能更深入地帮助我,那就太好了,我们可以打电话!
import React, { useEffect } from 'react';
import Row from '../row/row';
import './body.css';
import { nanoid } from 'nanoid';
export default function Body () {
const [boxMain, setBoxMain] = React.useState(null)
const [rows, setRows] = React.useState(null)
const ref = React.useRef(null)
function changeBox (event) {
console.log(event);
console.log(boxMain);
}
React.useEffect(() => {
/* Describes array with all information */
const sideBoxes = 40;
const heightContainer = ref.current.offsetHeight
const widthContainer = ref.current.offsetWidth;
const numRows = Math.floor(heightContainer / sideBoxes) - 1
const numBoxes = Math.floor(widthContainer / sideBoxes)
/* Beginning of array birth */
let main = Array(numRows).fill().map(() => new Array(numBoxes).fill({
id: "",
water: false,
land: false,
air: false,
}));
/* End of array birth */
const rows = []
for (let i = 0; i < numRows; i++) {
const id = nanoid();
rows.push(
<Row
key={id}
id={id}
rowNumber={i}
numBoxes={numBoxes}
sideBoxes={sideBoxes}
changeBox={changeBox}
main={main}
/>
)
}
setRows(rows)
setBoxMain(main)
}, [])
return (
<div>
<div onClick={() => changeBox("test")}>
TEST
</div>
<div ref={ref} className='body'>
{rows}
</div>
</div>
)
}
这里的示例 onClick={() => changeBox("test")
该函数可以正常工作并正确记录“boxMain”。但是当我将 changeBox={changeBox}
传递给 ...
import React, { useEffect } from "react";
import Box from "../box/box";
import "./row.css";
import { nanoid } from 'nanoid';
export default function Row (props) {
const ref = React.useRef(null)
const [boxes, setBoxes] = React.useState()
useEffect(() => {
const tempBoxes = []
for (let i = 0; i < props.numBoxes; i++) {
const id = nanoid()
tempBoxes.push(
<Box
rowNumber={props.rowNumber}
columnNumber={i}
key={id}
id={id}
side={props.sideBoxes}
changeBox={props.changeBox}
main={props.main}
/>
)
}
setBoxes(tempBoxes)
}, [])
return (
<div ref={ref} className="row-main">
{boxes}
</div>
)
}
然后将 changeBox={props.changeBox}
传递给 ...
import React from "react";
import "./box.css";
export default function Box (props) {
React.useEffect(() => {
props.main[props.rowNumber][props.columnNumber] = props.id
}, [])
const [detectChange, setDetectChange] = React.useState(0)
const ref = React.useRef(null)
const styles = {
width: `${props.side}px`,
height: `${props.side}px`,
}
return (
<div
ref={ref}
className="box-main"
key={props.id}
id={props.id}
rownumber={props.rowNumber}
columnnumber={props.columnNumber}
style={styles}
onClick={() => props.changeBox([props.id, props.rowNumber, props.columnNumber])}
>
</div>
)
}
然后我将 onClick={() => props.changeBox([props.id, props.rowNumber, props.columnNumber])}
和它 returns 到原始的 changeBox...
function changeBox (event) {
console.log(event);
console.log(boxMain);
}
但是当我单击该框时,它 returns 事件正确但 returns boxMain 为空。
当我单击 parent 函数中的 onClick 时,尽管它 console.log 一切正常。
我知道这是一大堆信息,但我知道修复必须很简单,或者至少我的方法应该改变。
感谢您的任何反馈!! :)
编辑 1:
这是正常的输出。
但是当我简单地在代码中添加一个 space 并将其保存在 VS Code 中时(我猜发生了某种类型的重新渲染?)然后它修复为...
尽管 ID 确实发生了变化,所以我认为一切都以某种方式刷新了。
Body
组件的 useEffect
钩子只运行一次,因为它没有任何依赖,因此 changeBox
传递给它的子和孙子的回调具有默认状态 boxMain
,它永远不会更新。
这就是为什么在 Body
组件中调用 changeBox
会正确记录 boxMain
数组,而在子组件中调用 props.changeBox
会正确记录 null
.
----------------解决方案--------------------
这不是最佳解决方案,但它会让您了解为什么它以前不起作用,以及如何解决它。
import React, { useEffect } from 'react';
import Row from '../row/row';
import './body.css';
import { nanoid } from 'nanoid';
export default function Body () {
const [boxMain, setBoxMain] = React.useState(null)
const [rows, setRows] = React.useState(null)
const [rowsData, setRowsData] = React.useState(null)
const ref = React.useRef(null)
function changeBox (event) {
console.log(event);
console.log(boxMain);
}
React.useEffect(() => {
/* Describes array with all information */
const sideBoxes = 40;
const heightContainer = ref.current.offsetHeight
const widthContainer = ref.current.offsetWidth;
const numRows = Math.floor(heightContainer / sideBoxes) - 1
const numBoxes = Math.floor(widthContainer / sideBoxes)
/* Beginning of array birth */
let main = Array(numRows).fill().map(() => new Array(numBoxes).fill({
id: "",
water: false,
land: false,
air: false,
}));
/* End of array birth */
const rowsData = []
for (let i = 0; i < numRows; i++) {
const id = nanoid();
rowsData.push({
key: id,
id,
rowNumber: id,
numBoxes,
sideBoxes,
})
}
setRowsData(rowsData)
setBoxMain(main)
}, [])
React.useEffect(() => {
const rows = []
for (let i = 0; i < rowsData?.length; i++) {
const id = nanoid();
const data = rowsData[i];
rows.push(
<Row
{...data}
changeBox={changeBox}
main={boxMain}
/>
)
}
setRows(rows)
}, [rowsData, boxMain, changeBox])
return (
<div>
<div onClick={() => changeBox("test")}>
TEST
</div>
<div ref={ref} className='body'>
{rows}
</div>
</div>
)
}
我会尽量用最好的方式表达这个...
当我通过道具将函数发送到 child,然后再次将其发送到另一个 child 时,然后使用点击在 'grandparent' 函数中激活它。当我 console.log 在 grandparent 中的原始函数中 console.log 是一个状态时,它打印未定义,但是当我在那个 grandparent 中并尝试激活该函数时,它将正确记录状态。如果有人能更深入地帮助我,那就太好了,我们可以打电话!
import React, { useEffect } from 'react';
import Row from '../row/row';
import './body.css';
import { nanoid } from 'nanoid';
export default function Body () {
const [boxMain, setBoxMain] = React.useState(null)
const [rows, setRows] = React.useState(null)
const ref = React.useRef(null)
function changeBox (event) {
console.log(event);
console.log(boxMain);
}
React.useEffect(() => {
/* Describes array with all information */
const sideBoxes = 40;
const heightContainer = ref.current.offsetHeight
const widthContainer = ref.current.offsetWidth;
const numRows = Math.floor(heightContainer / sideBoxes) - 1
const numBoxes = Math.floor(widthContainer / sideBoxes)
/* Beginning of array birth */
let main = Array(numRows).fill().map(() => new Array(numBoxes).fill({
id: "",
water: false,
land: false,
air: false,
}));
/* End of array birth */
const rows = []
for (let i = 0; i < numRows; i++) {
const id = nanoid();
rows.push(
<Row
key={id}
id={id}
rowNumber={i}
numBoxes={numBoxes}
sideBoxes={sideBoxes}
changeBox={changeBox}
main={main}
/>
)
}
setRows(rows)
setBoxMain(main)
}, [])
return (
<div>
<div onClick={() => changeBox("test")}>
TEST
</div>
<div ref={ref} className='body'>
{rows}
</div>
</div>
)
}
这里的示例 onClick={() => changeBox("test")
该函数可以正常工作并正确记录“boxMain”。但是当我将 changeBox={changeBox}
传递给 ...
import React, { useEffect } from "react";
import Box from "../box/box";
import "./row.css";
import { nanoid } from 'nanoid';
export default function Row (props) {
const ref = React.useRef(null)
const [boxes, setBoxes] = React.useState()
useEffect(() => {
const tempBoxes = []
for (let i = 0; i < props.numBoxes; i++) {
const id = nanoid()
tempBoxes.push(
<Box
rowNumber={props.rowNumber}
columnNumber={i}
key={id}
id={id}
side={props.sideBoxes}
changeBox={props.changeBox}
main={props.main}
/>
)
}
setBoxes(tempBoxes)
}, [])
return (
<div ref={ref} className="row-main">
{boxes}
</div>
)
}
然后将 changeBox={props.changeBox}
传递给 ...
import React from "react";
import "./box.css";
export default function Box (props) {
React.useEffect(() => {
props.main[props.rowNumber][props.columnNumber] = props.id
}, [])
const [detectChange, setDetectChange] = React.useState(0)
const ref = React.useRef(null)
const styles = {
width: `${props.side}px`,
height: `${props.side}px`,
}
return (
<div
ref={ref}
className="box-main"
key={props.id}
id={props.id}
rownumber={props.rowNumber}
columnnumber={props.columnNumber}
style={styles}
onClick={() => props.changeBox([props.id, props.rowNumber, props.columnNumber])}
>
</div>
)
}
然后我将 onClick={() => props.changeBox([props.id, props.rowNumber, props.columnNumber])}
和它 returns 到原始的 changeBox...
function changeBox (event) {
console.log(event);
console.log(boxMain);
}
但是当我单击该框时,它 returns 事件正确但 returns boxMain 为空。 当我单击 parent 函数中的 onClick 时,尽管它 console.log 一切正常。
我知道这是一大堆信息,但我知道修复必须很简单,或者至少我的方法应该改变。
感谢您的任何反馈!! :)
编辑 1:
这是正常的输出。
但是当我简单地在代码中添加一个 space 并将其保存在 VS Code 中时(我猜发生了某种类型的重新渲染?)然后它修复为...
尽管 ID 确实发生了变化,所以我认为一切都以某种方式刷新了。
Body
组件的 useEffect
钩子只运行一次,因为它没有任何依赖,因此 changeBox
传递给它的子和孙子的回调具有默认状态 boxMain
,它永远不会更新。
这就是为什么在 Body
组件中调用 changeBox
会正确记录 boxMain
数组,而在子组件中调用 props.changeBox
会正确记录 null
.
----------------解决方案--------------------
这不是最佳解决方案,但它会让您了解为什么它以前不起作用,以及如何解决它。
import React, { useEffect } from 'react';
import Row from '../row/row';
import './body.css';
import { nanoid } from 'nanoid';
export default function Body () {
const [boxMain, setBoxMain] = React.useState(null)
const [rows, setRows] = React.useState(null)
const [rowsData, setRowsData] = React.useState(null)
const ref = React.useRef(null)
function changeBox (event) {
console.log(event);
console.log(boxMain);
}
React.useEffect(() => {
/* Describes array with all information */
const sideBoxes = 40;
const heightContainer = ref.current.offsetHeight
const widthContainer = ref.current.offsetWidth;
const numRows = Math.floor(heightContainer / sideBoxes) - 1
const numBoxes = Math.floor(widthContainer / sideBoxes)
/* Beginning of array birth */
let main = Array(numRows).fill().map(() => new Array(numBoxes).fill({
id: "",
water: false,
land: false,
air: false,
}));
/* End of array birth */
const rowsData = []
for (let i = 0; i < numRows; i++) {
const id = nanoid();
rowsData.push({
key: id,
id,
rowNumber: id,
numBoxes,
sideBoxes,
})
}
setRowsData(rowsData)
setBoxMain(main)
}, [])
React.useEffect(() => {
const rows = []
for (let i = 0; i < rowsData?.length; i++) {
const id = nanoid();
const data = rowsData[i];
rows.push(
<Row
{...data}
changeBox={changeBox}
main={boxMain}
/>
)
}
setRows(rows)
}, [rowsData, boxMain, changeBox])
return (
<div>
<div onClick={() => changeBox("test")}>
TEST
</div>
<div ref={ref} className='body'>
{rows}
</div>
</div>
)
}