Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/reactjs/25.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 在内部组件中使用挂钩_Javascript_Reactjs_React Hooks_Use Effect - Fatal编程技术网

Javascript 在内部组件中使用挂钩

Javascript 在内部组件中使用挂钩,javascript,reactjs,react-hooks,use-effect,Javascript,Reactjs,React Hooks,Use Effect,我试图用钩子创建组件,但我遇到了一个奇怪的问题。 我在代码中使用mapbox gl。为了初始化mapbox gl,我必须等待dom组件加载。(使用布局效果或使用效果) 初始显示没有问题,但当我按下按钮(L72)时,由mapbox gl创建的画布将卸载,没有控制台错误。 我尝试将MyMap组件移到平铺组件(L35-L45)之外,然后上述问题没有发生 我是不是用错钩子了 我的完整代码示例如下。 这是Map.tsx中的摘录: export const Tile: React.FunctionComp

我试图用钩子创建组件,但我遇到了一个奇怪的问题。
我在代码中使用mapbox gl。为了初始化mapbox gl,我必须等待dom组件加载。(使用布局效果或使用效果)
初始显示没有问题,但当我按下按钮(L72)时,由mapbox gl创建的画布将卸载,没有控制台错误。
我尝试将MyMap组件移到平铺组件(L35-L45)之外,然后上述问题没有发生

我是不是用错钩子了

我的完整代码示例如下。

这是Map.tsx中的摘录:

export const Tile: React.FunctionComponent<PropsType> = ({
  mapComponentLoaded,
  trigger,
  triggered
}) => {
  const classes = useStyles({});

  React.useLayoutEffect(() => { // or useEffect
    // init mapbox-gl
    mapComponentLoaded();
  }, []); // run at once

  // it doesn't works. if you clicked the button, the canvas under div#map would unmount.
  const MyMap = (props: { triggered: boolean }) => (
    <Paper className={classes.content}>
      <div id="map" className={classes.map} />
      <Typography>{props.triggered ? "fired" : "not fired"}</Typography>
    </Paper>
  );

  return (
    <div className={classes.root}>
      <Grid container spacing={1} className={classes.root}>
        <Grid item xs={12}>
          <Button variant="contained" color="primary" onClick={() => trigger()}>
            Add Boundary
          </Button>
        </Grid>
        <Grid item xs={12} className={classes.map}>
          <MyMap triggered={triggered} />
        </Grid>
      </Grid>
    </div>
  );
};
export const Tile:React.FunctionComponent=({
mapComponentLoaded,
触发
触发
}) => {
const classes=useStyles({});
React.useLayoutEffect(()=>{//或useEffect
//初始化映射框gl
mapComponentLoaded();
},[]);//立即运行
//它不起作用。如果单击该按钮,div#map下的画布将卸载。
常量MyMap=(属性:{触发:布尔值})=>(
{props.triggered?“fired”:“not fired”}
);
返回(
触发器()}>
添加边界
);
};

谢谢。

当您在功能组件中定义组件时,在每次渲染时都会创建一个新的组件引用,因此,在创建一个新组件时,react不会重新渲染,而是重新装载它

当您将组件从功能组件中取出时,函数的引用不会更改,因此react会正确地渲染它

现在,另一种方法是,如果不将
MyMap
作为组件呈现,而是将其作为函数调用

export const Tile: React.FunctionComponent<PropsType> = ({
  mapComponentLoaded,
  trigger,
  triggered
}) => {
  const classes = useStyles({});

  React.useLayoutEffect(() => { // or useEffect
    // init mapbox-gl
    mapComponentLoaded();
  }, []); // run at once

  // it doesn't works. if you clicked the button, the canvas under div#map would unmount.
  const MyMap = (props: { triggered: boolean }) => (
    <Paper className={classes.content}>
      <div id="map" className={classes.map} />
      <Typography>{props.triggered ? "fired" : "not fired"}</Typography>
    </Paper>
  );

  return (
    <div className={classes.root}>
      <Grid container spacing={1} className={classes.root}>
        <Grid item xs={12}>
          <Button variant="contained" color="primary" onClick={() => trigger()}>
            Add Boundary
          </Button>
        </Grid>
        <Grid item xs={12} className={classes.map}>
          {MyMap({triggered})}
        </Grid>
      </Grid>
    </div>
  );
};
export const Tile:React.FunctionComponent=({
mapComponentLoaded,
触发
触发
}) => {
const classes=useStyles({});
React.useLayoutEffect(()=>{//或useEffect
//初始化映射框gl
mapComponentLoaded();
},[]);//立即运行
//它不起作用。如果单击该按钮,div#map下的画布将卸载。
常量MyMap=(属性:{触发:布尔值})=>(
{props.triggered?“fired”:“not fired”}
);
返回(
触发器()}>
添加边界
{MyMap({triggered}}}
);
};

p.S.但是,将定义从函数定义中删除是一种更好的方法,因为它可以灵活地添加更多 使用
React.memo
和使用挂钩进行性能优化 在这个组成部分内


不要在另一个组件内声明组件。它将重新装载每个渲染。感谢您的详细回答。我想我明白了,但我有一个问题。JSX风格和函数调用之间有什么区别?我认为两者都可能被编译为
React.createElement()
。可能当您将其作为组件呈现时,React会关心引用,当您从函数返回时,它会比较元素类型和道具以及键。虽然我还没有在React代码中检查这件事