在变量更改时渲染功能组件

时间:2019-05-14 07:38:32

标签: javascript reactjs

内部变量更改时,我无法重新渲染组件。我正在研究的系统使用功能组件。情况是这样的:

export const myComponent = (props: compPropsType) => {
    const myClassNames ....

    let objectList= getObjectList(window.location.hash, props.pageTree);

    window.addEventListener('hashchange', () => {
        console.log('hello');
        objectList = getObjectList(window.location.hash, props.pageTree);
    });
    return (
        <>
        <header className={headerClassNames}>
            <Block className={...}>
            ...
            <myChildComp objList={objectList}>
            ...
    )
};

问题是散列更新时呈现<myCildComp>。 (objectList是一个字符串数组,用于创建导航工具栏。)

当我单击页面上的链接时,hello被写入控制台,因此侦听器正在工作,但不会重新呈现子组件。

2 个答案:

答案 0 :(得分:1)

react中的函数组件等效于类组件中的render()函数。

因此,在您的情况下,每次重新渲染组件时都会添加一个eventListener,这会导致内存泄漏,您应该使用useEffect钩子来添加一次,并在组件/钩子被删除时将其删除。毁了。

您的组件不会重新渲染,因为什么都没有告诉它。.仅当状态或道具发生更改时,组件的响应才重新渲染..因此,在您的情况下,我认为您需要将objectList添加到state像这样useEffect钩子

export const myComponent = (props: compPropsType) => {
    const myClassNames ....
     const [objectList, setObjectList] = useState([])

  const onHashChanged = () => {
    console.log('hello')

    let newObjectList = getObjectList(window.location.hash, props.pageTree)
    setObjectList(newObjectList)
  }

  useEffect(() => {
    window.addEventListener('hashchange', onHashChanged)
    return () => window.removeEventListener('hashchange', onHashChanged)
  }, [])
    return (
        <>
        <header className={headerClassNames}>
            <Block className={...}>
            ...
            <myChildComp objList={objectList}>
            ...
    )
};

当在useEffect中使用空数组作为第二个参数时,它将仅被调用一次等效于componentDidMount,并且我将返回一个回调函数以取消订阅/删除与{ {1}}

答案 1 :(得分:0)

如评论中所建议,我将函数重写为一个类:

export class myComponent extends React.PureComponent<PropsTypes> {
    constructor(props) {
        super(props)
        this.state = {objList = getObjectList(window.location.hash, this.props.pageTree)};
    }
    componentDidMount(): void {
        window.addEventListener('hashchange', () => {
            this.setState({
            breadcrumbList: getObjList(window.location.hash, this.props.pageTree),
            });
        });
    }
    render() {
    return (....
        <myChildComp objList={this.state.objList}>
    ...

这行得通,但这是最好的方法吗?