Преобразование компонента класса React в компонент React Hook - PullRequest
0 голосов
/ 29 мая 2020

Я хочу преобразовать этот компонент класса реакции в компонент хуков реакции. Я преобразовал большую часть кода, и теперь мне нужна помощь в преобразовании части кода, которая находится между функциями рендеринга и возврата.

Вот компонент класса:

class LoginGoogle extends React.Component {
    state = {
        loading: true,
        error: null,
        data: {},
    };

    componentDidMount() {
        fetch(`/api/auth/google/callback${this.props.location.search}`, { headers: new Headers({ accept: 'application/json' }) })
            .then((response) => {
                if (response.ok) {
                    return response.json();
                }
                throw new Error('Something went wrong!');
            })
            .then((data) => {
                this.setState({ loading: false, data });
            })
            .catch((error) => {
                this.setState({ loading: false, error });
                console.error(error);
            });
    }

    render() {
        const { loading, error, data } = this.state;
        if (loading) {
            return <Layout>Loading....</Layout>;
        }

        if (error) {
            return (
                <Layout>
                    <div>
                        <p>Error:</p>
                        <code className="Code-block">{error.toString()}</code>
                    </div>
                </Layout>
            );
        }

        return (
            <Layout>
                <div>
                    <details>
                        <summary>Welcome {data.user.name}</summary>
                        <p>Here is your info: </p>
                        <code className="Code-block">{JSON.stringify(data, null, 2)}</code>
                    </details>
                </div>
            </Layout>
        );
    }
}

А это - это новый созданный мной компонент перехватчиков реакции. Как я упоминал ранее, он еще не закончен.

function LoginGoogle (props) {

    const [start, setStart] = useState(
        {
        loading: true,
        error: null,
        data: {},
           }
    )

    useEffect(() => {
        fetch(`/api/auth/google/callback${props.location.search}`, { headers: new Headers({ accept: 'application/json' }) })
            .then((response) => {
                if (response.ok) {
                    return response.json();
                }
                throw new Error('Something went wrong!');
            })
            .then((data) => {
                setStart({ loading: false, data });
            })
            .catch((error) => {
                setStart({ loading: false, error });
                console.error(error);
            });
    })


        const { loading, error, data } = this.state;
        if (loading) {
            return <Layout>Loading....</Layout>;
        }

        if (error) {
            return (
                <Layout>
                    <div>
                        <p>Error:</p>
                        <code className="Code-block">{error.toString()}</code>
                    </div>
                </Layout>
            );
        }

        return (
            <Layout>
                <div>
                    <details>
                        <summary>Welcome {data.user.name}</summary>
                        <p>Here is your info: </p>
                        <code className="Code-block">{JSON.stringify(data, null, 2)}</code>
                    </details>
                </div>
            </Layout>
        );
    }

Вот шаги, которые я предпринял для преобразования кода: 10 шагов для преобразования компонента класса React в функциональный компонент React с хуками !

Ответы [ 2 ]

2 голосов
/ 29 мая 2020

Прежде всего, logi c из componentDidMount должен находиться внутри ловушки useEffect, что вы правильно поняли. Однако вам нужно будет добавить пустой массив в качестве массива зависимостей, который гарантирует, что HTTP-запрос будет вызван один раз при монтировании:

useEffect(() => {
    fetch(`/api/auth/google/callback${props.location.search}`, { headers: new Headers({ accept: 'application/json' }) })
        .then((response) => {
            if (response.ok) {
                return response.json();
            }
            throw new Error('Something went wrong!');
        })
        .then((data) => {
            setStart({ loading: false, data });
        })
        .catch((error) => {
            setStart({ loading: false, error });
            console.error(error);
        });
}, []);

При этом вы должны условно визуализировать элементы JSX на основе состояние вашего компонента, как определено start состоянием:

const { data, error, loading } = start;

return (
  <>
    {error && (
       <Layout>
         <div>
           <p>Error:</p>
           <code className="Code-block">{error.toString()}</code>
           </div>
       </Layout>
    )}
    {data && (
      <Layout>
        <div>
           <details>
             <summary>Welcome {data.user.name}</summary>
             <p>Here is your info: </p>
             <code className="Code-block">{JSON.stringify(data, null, 2)}</code>     </details>
         </div>
      </Layout>
    )}
    {
      loading && <Layout>Loading....</Layout>
    }
  <>
);
1 голос
/ 29 мая 2020

Прямо сейчас ваш запрос на выборку выполняется для КАЖДОЙ визуализации, если вы хотите смоделировать поведение componentDidMount, вам нужно будет передать пустой массив зависимостей в useEffect

useEffect(() => {
    fetch(`/api/auth/google/callback${props.location.search}`, { headers: new Headers({ accept: 'application/json' }) })
        .then((response) => {
            if (response.ok) {
                return response.json();
            }
            throw new Error('Something went wrong!');
        })
        .then((data) => {
            setStart({ loading: false, data });
        })
        .catch((error) => {
            setStart({ loading: false, error });
            console.error(error);
        });
}, []) // See the empty dependency array

Добавив пустой список зависимостей, он будет запущен один раз.

const { loading, error, data } = this.state

становится

const {loading, error, data} = start

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...