如何在使用React钩子时初始化第三方库?

时间:2019-08-04 09:28:50

标签: reactjs react-hooks

如果我有一个第三方库,通常我会这样初始化:

class App {
  constructor(props) {
    this.helperLibrary = new HelperLibrary();
    this.state = { data: null };
  }
}

我该如何使用React钩子在功能组件中对其进行初始化?

所以更新后的代码如下:

const App = () => {
  const [data, setData] = useState(null);

  // Would I write something like this here??
  helperLibrary = new HelperLibrary();

  // Or would I use something like useEffect since
  // constructor runs when the component is created?

  useEffect = (() => {
    helperLibrary = new HelperLibrary();
  }, []);
};

7 个答案:

答案 0 :(得分:3)

一种简单的方法是在组件外部进行初始化:

const helperLibrary = new HelperLibrary();

const App = () => {
  const [data, setData] = useState(null);
};


如果您需要有条件地对其进行初始化,则在App即将第一次呈现之前(而不是在其他路径中),构造函数的最接近等价物如下:

const App = () => {
  const helperLibrary = useRef(null);
  const [data, setData] = useState(null);

  // note: useEffect would run AFTER first render, equivalent of componentDidMount,
  //       for equivalent of consturctor, we need sync code, e.g.:
  if (!helperLibrary.current) {
    helperLibrary.current = new HelperLibrary();
  }
};

答案 1 :(得分:1)

我认为使用此方法很有意义,因为在安装组件时,该函数只会被调用一次,因此应该在此块中完成库的初始化。

useEffect(() => {
         console.log('mounted the component');
         helperLibrary = new HelperLibrary();
   }, [])

答案 2 :(得分:0)

// This will init when this file is imported. 
// If you will use the library in multiple components, 
// they will reinit each time you use this syntax.
helperLibrary = new HelperLibrary();

const App = () => {
    const [data, setData] = useState(null);

    // This will reinit on every render
    helperLibrary = new HelperLibrary();

    useEffect = (() => {
        // This will also reinit on every render
        helperLibrary = new HelperLibrary();
    }, []);
}

要拥有此HelperLibrary()的单个实例,可以通过

将其初始化到另一个文件上
  // You can call this from many files, and only one instance of this class will be used.
  export helperLibrary = new HelperLibrary();

然后您可以将其导入其他文件

import {helperLibrary} from './HelperLibrary';

const App = () => {
    const [data, setData] = useState(null);

    useEffect = (() => {
       helperLibrary.doSomething();
    }, []);

为此我做了一个小型研讨会,您可以在这里看到:https://codesandbox.io/s/react-hooks-counter-demo-ppkjq

答案 3 :(得分:0)

在我们的案例中,我们需要将第三方库绑定到DOM元素,并将props传递给init。我最终一起使用了useRef和useEffect:

const App = (props) => {
  const container = useRef()
  const helperLibrary = useRef(null)
  const [data, setData] = useState(null);

  useEffect = (() => {
    if (!helperLibrary.current) { // runs only once
      helperLibrary.current = new HelperLibrary({
        props,
        // this needs to be last so it doesn't get owerwritten
        container: container.current 
      })
    } else { // if there is a way to update
      helperLibrary.current.update({
        props
      })
    }
  }, [props]);

  return (
    <div ref={container} />
  );
}

答案 4 :(得分:0)

如果您需要在组件卸载后销毁实例

const App = () => {
  const [helperLibrary, setHelperLibrary] = useState(null);
  const [data, setData] = useState(null);

  useEffect(() => {
     const helperLibaryInstance = new HelperLibrary();
     setHelperLibrary(helperLibaryInstance);

     return () => {
        helperLibaryInstance.destroy()
     }
  }, [])

  ...

  return helperLibrary && (
     <Component />
  )
};

其他

const App = () => {
  const [data, setData] = useState(null);

  const helperLibrary = useMemo(() => {
     const helperLibaryInstance = new HelperLibrary();
     return helperLibaryInstance;
  }, [])

  ...

  return (
     <Component />
  )
};

答案 5 :(得分:0)

另一个使用 Plyr 作为第三方库同时使用 React 钩子的例子。

function returnDay(n){
    day = daysOfWeek[n-1];
    if (n  > 7 || n  < 1){
        return null
    } else {
        return day
    }
}
console.log(returnDay(8))
console.log(returnDay(0))

答案 6 :(得分:-1)

对于挂钩中的无状态组件,请使用语法作为函数。这是React的建议。

我建议将新的第三个库作为参考保存。请记住,如果使用钩子useRef,则需要在该钩子中保存当前的对象。 像这样

public function configureOptions(OptionsResolver $resolver)
{
    $resolver->setDefaults([
        'class' => MealPlanHotel::class,
        'query_builder' => function (Options $options) {
            return function(EntityRepository $er) use($options) {
                return $er->createQueryBuilder('meals')
                    ->where('meals.hotel = :hotel')->setParameter('hotel', $options['hotel'])
                    ->andWhere('meals.isEnabled = true')
                    ->orderBy('meals.sortIndex', 'ASC');
            };
        },

    ]);

    $resolver->setRequired(['hotel']);
}