React Hooks D3 和 Isotope 库拥有状态

问题描述

我正在尝试重构我现有的代码以使用 Hooks 而不是构造函数、componentDidMount()、componentDidUpdate()。我下面的原始代码做得很好:

import React from "react";
import '../css/App.css';
import 'jquery/dist/jquery.js';
import Isotope from 'isotope-layout/dist/isotope.pkgd.min.js';  
import projectsData from '../data/projectsData';
import Project from './Projects';

    class App extends React.Component {

  constructor(props){
    super(props);
    this.state = { 
      isotope: null,projectComponents: projectsData.map(project => <Project id={project.id} project={project}/>),}
 }

  componentDidMount() {

    //load isotope masonry view
    const elem = document.querySelector('#visContainer')
    if (!this.state.isotope) {
      this.setState({
        isotope: new Isotope( elem,{
          //options
          itemSelector: '.gridItem',layoutMode: 'masonry',masonry: {
            columnWidth: 140,fitWidth: true
          },getSortData: {
            year: '.yearsstart parseFloat',kind: '.kind'
          }
        })
      });
    }
    else {
      this.state.isotope.reloadItems();
    }
  }
  }
    componentDidUpdate() {
      if (this.state.isotope) {
        this.state.isotope.reloadItems();
        this.state.isotope.layout();
      }
    }
  render(){


    return (
      <body>
        <div id='sepLine'>
        <div id="visHolder">
           <div id="visContainer" style={{position: "relative",width: "840px",height: "1823px"}}>
             {this.state.projectComponents} 
           </div>           
         </div>
       </div>
      </body>
    );
  }
 
}

export default App

但是,我试图修改它以使用 d3 库而不是映射外部组件(项目)。 并使用 React Hooks 执行此操作。 我在下面使用 d3 映射数据,但我无法将 Isotope 应用于 ID“visContainer”。 我怀疑这是因为它们同时发生,因为它们都在使用 useEffect()?:

import React,{ useEffect,useState } from "react";
import '../css/App.css';
import 'jquery/dist/jquery.js';
import Isotope from 'isotope-layout/dist/isotope.pkgd.min.js';  
import projectsData from '../data/projectsData';
import Project from './Projects';

function App () {
  const [isotope,setIsotope] = useState(null);

  useEffect(() => {
    const projects = d3.select('#visContainer');
    projects
    .selectAll('.lineDiv')
    .data(projectsData)
    .enter()
    .append('div')
    .attr('id',(d,i) => { 
      return d.title })
        .attr('className',d => {
      return 'lineDiv gridItem y' + d.start.substring(0,4) + ' ' + d.kind + ' ' + d.title + ' ' + d.subtitle.replace(/,/g,' ');
    })
  },[]);

  useEffect(() => {
    const elem = document.querySelector('#visContainer')  
      setIsotope(new Isotope( elem,{
          itemSelector: '.gridItem',kind: '.kind'
          }
        })
      )
    },[]);
    return (
      <body>
        <div id='sepLine'>
        <div id="visHolder">
           <div id="visContainer" style={{position: "relative",height: "1823px"}}>
           </div>           
         </div>
       </div>
      </body>
    );
  }

export default App

非常感谢任何帮助,因为我很想知道我可以将 React Hooks 推多远。提前致谢!

解决方法

我通过在初始加载到 setProjects() 和映射时使用“useEffect”来解决这个问题。然后 Isotope 使用

控制“#visContainer”
document.querySelector('#visContainer') 
const App = (props) => {
  const [projects,setProjects] = useState(null);
  const [isotope,setIsotope] = useState(null);

  
  useEffect(() => {
    setProjects(projectsData.map(project => <Project id={project.id} project={project} onClick={filterThisProject}/>))
  },[])

  useEffect(() => {
    const elem = document.querySelector('#visContainer')  
      setIsotope(new Isotope( elem,{
          itemSelector: '.gridItem',layoutMode: 'masonry',masonry: {
            columnWidth: 140,fitWidth: true
          },getSortData: {
            year: '.start parseFloat',kind: '.kind'
          }
        })
      )
    },[projects]);


    return (
      <body>
        <div id='sepLine'>
        <div id="visHolder">
           <div id="visContainer" style={{position: "relative",width: "840px",height: "1823px"}} >
             {projects}
           </div>           
         </div>
       </div>
      </body>
    );
}

export default App;
  

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...