React 16中具有功能组件的HOC和渲染道具

时间:2019-12-25 20:45:47

标签: reactjs

我对React中的功能组件与Render Props和HOC模式之间的关系有些困惑。

创建Render Prop的唯一方法是使用类组件吗? 是不是创建HOC的唯一方法是使用类组件?

与用法相同。

我正在尝试查找带有功能组件的Render Props和HOC的示例,而我发现的全部都是类组件。我知道React Hooks可以做很多相同的事情,但是我试图了解Render Props和HOC模式如何应用于功能组件(或者是否可以完全使用)


在下面编辑:

应用@chaimFriedman的建议,这就是我没有使用类或组件进行HOC的想法,希望它有意义。

import React, { useState, useEffect } from 'react';
import useAxios from 'axios-hooks';

function withFetching(url) {
  return function(Speakers) {
    return () => {
      const [speakerData, setSpeakerData] = useState([]);
      const [isLoading, setIsLoading] = useState(true);
      const [{ data, loading }, refetch] = useAxios('http://localhost:4000/speakers');
      useEffect(() => {
        setSpeakerData(data);
        setIsLoading(loading);
      }, [loading]);

      if (isLoading) return <div>loading..</div>;

      return <Speakers data={speakerData}></Speakers>;
    };
  };
}

const Speakers = function(props) {
  //debugger;
  return (
    <ul>
      {props.data.map((speaker) => (
        <li key={speaker.id}>
          <span>
            {speaker.firstName} {speaker.lastName}
          </span>
        </li>
      ))}
    </ul>
  );
};

const API = 'http://localhost:4000/speakers';
export default withFetching(API)(Speakers);

2 个答案:

答案 0 :(得分:3)

渲染道具和HOC都可以绝对应用于功能组件。让我们再思考一下每个人实际上是什么,看看他们为什么实际上对函数和类都起作用。

渲染道具是指您拥有的道具是可以返回JSX的函数。这当然应该适用于功能组件,因为除生命周期方法外,实际上与类组件没有太多不同。这是带有代码的示例。

import React from "react";
import ReactDOM from "react-dom";

import "./styles.css";

function Renderer(props) {
  return (
    props.children()
  );
}

function App() {
  return (
    <div className="App">
      <Renderer>
        {() => {
          return (
            <h1>I am being rendered by Renderer</h1>
          );
        }}
      </Renderer>
    </div>
  );
}

const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);

现在开始HOC。

HOC实际上只是一个高阶函数,但是由于我们在反应中使用它,因此将其称为高阶组件。高阶函数是接受函数作为参数或返回函数的函数。现在,功能组件绝对可以做到这一点。这是一个例子。

import React from "react";
import ReactDOM from "react-dom";

import "./styles.css";

function Renderer(Wrapped) {
  return function New(props) {
    return <Wrapped {...props} />
  }
}

function Child(props) {
  return (
    <h1>Hello {props.name}</h1>
  );
}

function App() {
  const C = Renderer(Child)
  return (
    <div className="App">
     <C name="john" />
    </div>
  );
}

const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);

编辑:我意识到我的HOC示例是错误的,所以更新了。

我希望这会有所帮助。

答案 1 :(得分:1)

这是将 React 文档中的示例代码转换为函数组件的示例代码。 https://reactjs.org/docs/render-props.html

import React from "react";

const Cat = ({mouse}) => {
  return (
    <img
      src="/cat.png"
      alt="cat"
      style={{ position: "absolute", left: mouse.x, top: mouse.y }}
    />
  );
};

const Mouse = (props) => {
  const [state, setState] = React.useState();

  const handleMouseMove = (event) => {
    setState({
      x: event.clientX,
      y: event.clientY
    });
  };
  
  return (
    <div style={{ height: "100vh" }} onMouseMove={handleMouseMove}>
      {props.render(state)}
    </div>
  );
};

const MouseTracker = () => {
  return (
    <div>
      <h1>Move the mouse around!</h1>
      <Mouse render={(mouse) => <Cat mouse={mouse} />} />
    </div>
  );
};

export const App = () => {
  return (
    <div className="App">
      <MouseTracker />
    </div>
  );
}