错误:无效的钩子调用-在react-router useHistory中

时间:2020-06-14 09:56:54

标签: javascript reactjs react-router react-hooks

我正在类组件中使用功能组件,并通过编程方式将onClick重定向为react-router

这有效:

const Child => () => {
  let history = useHistory();
  return (
    <div onClick={() => history.push('/somewhere')}>Click me!</div>
  )
}

class App extends React.Component {

  render() {
    return <div><Child /></div>
  }
}

但是如果我有 N 个孩子,并且我像这样做.map

class App extends React.Component {

  const children = ['a', 'b'].map(Child);
  render() {
    return <div>{children}</div>
  }
}

然后我得到:

错误:无效的挂钩调用。挂钩只能在功能组件的主体内部调用。

我不明白为什么这是一个错误。如果我忽略该规则,例如:

// eslint-disable-next-line react-hooks/rules-of-hooks
let history = useHistory();

然后它起作用了,但是我在做一些反模式吗?我确实在函数组件的主体内部调用了钩子……但是它没有直接呈现为JSX元素的直接子代。

在这种情况下如何使用useHistory挂钩?我在做什么错了?

3 个答案:

答案 0 :(得分:2)

问题:

.map(Child),此处Child视为 simple function,而未被视为 functional component,并且地图功能正在直接调用

因此,结果react引发错误:只能在函数组件的主体内部调用挂钩。

与以下代码段相同:

function square(a) {
  return a*a;
}

console.log([1,2,3].map(square))


解决方案:

更改此内容:

children = ['a', 'b'].map(Child);

收件人:

children = ['a', 'b'].map((e,i) => <Child key={i}/>); // <--- provide key also 

工作演示:

Edit #SO-functional-component-issue

答案 1 :(得分:1)

const children = ['a','b']。map(Child);不正确的替换为:

class App extends React.Component {
  children = ["a", "b"];
  render() {
    return children.map((el, i) => <Child key={i} />);
  }
}

答案 2 :(得分:0)

在您的App.js文件中将<Route exact path='/' render={Content} />更改为<Route exact path='/' component={Content} />