首页 > 解决方案 > 为什么 React 组件只有在我刷新页面后才能工作?

问题描述

我有一个名为 Tools 的组件,当我在路线上时可以访问它tools/:id。在此页面上,我有与Links此页面相关的按钮,但单击时它会将不同的 id 传递给 URL,以便显示不同的工具。

getTool 方法只是返回正确的组件,并且该组件将只有一个东西,一个 iFrame 来显示来自另一个网站的计算器。

因此,当我在工具之间来回切换时,直到我单击刷新,工具才会加载。否则,我会收到一条错误消息TypeError: Cannot read property 'style' of null。这是因为我有document.getElementById('calc-SOME-NUMBER'),但 SOME_NUMBER 仍然指的是我使用的最后一个工具。此声明在每个工具中,您可以在下面的BCalc.

我检查了状态,当我在工具之间来回切换时,一切都是正确的;正确的工具放置在减速器中。知道为什么会这样吗?我将history.go()其用作解决方法,因为我看不出它仍然存在于旧工具 ID 上的任何原因。

const Tool = ({
  getContent,
  closeContent,
  content: { content, loading, contents },
  user,
  match,
}) => {
  const history = useHistory();

  useEffect(() => {
    scrollToTop();
    getContent(match.params.id);
    return () => {
      logView(user, match.params.id, "tool");
      closeContent();
      history.go(); // doesn't work without this line
    };
  }, [getContent, closeContent, match.params.id, user]);

  let ToolComponent;

  const listItemStyle = { paddingTop: "40px", paddingBottom: "40px" };

  return loading || content === null ? (
    <Spinner />
  ) : (
    <Container
      style={{ marginTop: "3%" }}
      fluid="true"
      className="contentCardBody"
    >
      <Card>
       <Card.Body>
          {(ToolComponent = getTool(content.content_id.path))}
                <ToolComponent />
        </Card.Body>
      </Card>
    </Container>
  );
};

Tool.propTypes = {
  content: PropTypes.object.isRequired,
  user: PropTypes.object.isRequired,
  getContent: PropTypes.func.isRequired,
  closeContent: PropTypes.func.isRequired,
};

const mapStateToProps = (state) => ({
  content: state.content,
  user: state.auth.user,
});

export default connect(mapStateToProps, {
  getContent,
  closeContent,
})(Tool);

此外,这里是从 getTool() 返回的示例:

const BCalc = () => {
  const eventMethod = window.addEventListener ? 'addEventListener' : 'attachEvent';
  const eventer = window[eventMethod];
  const messageEvent = eventMethod === 'attachEvent' ? 'onmessage' : 'message';
  eventer(
    messageEvent,
    (e) => {
      if (e.origin === 'https://EXAMPLE.com') {
        if (e.data.startsWith('height;')) {
          document.getElementById('calc-SOME_NUMBER').style.height = `${e.data.split('height;')[1]}px`;
        } else if (e.data.startsWith('url;')) {
          window.location.href = e.data.split('url;')[1];
        }
      }
    },
    !1,
  );

  return (
    <div>
      <iframe
        id="calc-SOME_NUMBER"
        src="https://EXAMPLE_CALC"
        title="tool"
        scrolling="no"
        style={{
          width: '100%',
          border: 'none',
          marginTop: '-2%',
          zIndex: '-1',
        }}
      />
    </div>
  );
};

export default BCalc;

标签: reactjsreact-redux

解决方案


推荐阅读