ryuto-ikeuchi
@ryuto-ikeuchi (池内 隆人)

Are you sure you want to delete the question?

If your question is resolved, you may close it.

Leaving a resolved question undeleted may help others!

We hope you find it useful!

useEffectはApp.jsじゃないと使えない!?

ローカル上だとちゃんと作動しますがデプロイするとエラーになります。

現在Reactで写真を検索して表示するアプリを作っています。
一通り上手く実装できたのでコンポーネント化しようとしたところエラーが発生しました

発生している問題・エラー

Search for the keywords to learn more about each warning.
To ignore, add // eslint-disable-next-line to the line before.

エラーではないですが何かwarningがででいます。

該当するソースコード

import React, { useState } from 'react';
import './App.css';
import { Search } from './components/Search';

export const App = () => {
    const [images, setImages] = useState([]);

    return (
        <div className="App">
            <Search setImages={setImages} />

            <div className="container">
                {images.map((image) => (
                    <div key={image.id} className="card">
                        <img src={image.urls.regular} className="card-img" alt="" />
                        <div className="card-content">
                            <div className="card-title">{image.alt_description}</div>
                        </div>
                        <div className="card-name">
                            <img
                                src={image.user.profile_image.small}
                                className="card-thumb"
                                alt=""
                            />
                            <p className="card-author">{image.user.first_name}</p>
                        </div>
                    </div>
                ))}
            </div>
        </div>
    );
};

↑こちらがもともと記述してあったapp.jsxです

import React, { useState,useEffect } from 'react';

export const Search = ({setImages}) => {
    const [text, setText] = useState('');
    const [query, setQuery] = useState('soccer');

    const onSubmit = (e) => {
        e.preventDefault();
        setQuery(text);
        setText('');
        console.log('onSubmit');
    };

    useEffect(() => {
        console.log('useEffect');
        fetch(
            `https://api.unsplash.com/search/photos?query=${query}&client_id=${process.env.REACT_APP_CLIENT_ID}`
        )
            .then((Response) => Response.json())
            .then((data) => {
                console.log(data);
                setImages(data.results);
            });
    }, [query]);


    return (
        <React.Fragment>
            <div className="main">
                <div className="header">
                    <p>search photo app</p>
                </div>
                <form onSubmit={onSubmit}>
                    <input
                        type="text"
                        onChange={(e) => setText(e.target.value)}
                        value={text}
                        placeholder="search photos name"
                    />
                    <button type="submit">Search</button>
                </form>
                <div className="example">for example:apple,baseball</div>
            </div>
        </React.Fragment>
    );
};

↑こちらが今回コンポーネント化して抜き出した箇所です

自分で試したこと

import React, { useState, useEffect } from 'react';
import './App.css';
import { Search } from './components/Search';

export const App = () => {
    const [images, setImages] = useState([]);
    const [query, setQuery] = useState('soccer');

    useEffect(() => {
        console.log('useEffect');
        fetch(
            `https://api.unsplash.com/search/photos?query=${query}&client_id=${process.env.REACT_APP_CLIENT_ID}`
        )
            .then((Response) => Response.json())
            .then((data) => {
                console.log(data);
                setImages(data.results);
            });
    }, [query]);

    return (
        <div className="App">
            <Search setQuery={setQuery} />

            <div className="container">
                {images.map((image) => (
                    <div key={image.id} className="card">
                        <img src={image.urls.regular} className="card-img" alt="" />
                        <div className="card-content">
                            <div className="card-title">{image.alt_description}</div>
                        </div>
                        <div className="card-name">
                            <img
                                src={image.user.profile_image.small}
                                className="card-thumb"
                                alt=""
                            />
                            <p className="card-author">{image.user.first_name}</p>
                        </div>
                    </div>
                ))}
            </div>
        </div>
    );
};

↑useEffectをapp.jsxに持っていきました
そのためsetQueryをSearchコンポーネントに持たせました。

すると

You can now view react-pic-app in the browser.

  Local:            http://localhost:3000
  On Your Network:  http://192.168.2.100:3000

Note that the development build is not optimized.
To create a production build, use yarn build.

警告文がなくなり、vercelでもデプロイが上手くできました。

useEffectは原則App.jsx上で使わないといけないとか決まりがあるのでしょうか?
今回だとコンポーネント化で間違っていることをしていたらご指摘いただけますと幸いです

0

1Answer

見たところeslintからのメッセージっぽいですが、これだけだとそこから先はだいぶわからないですね……
もう少し上のメッセージか、コマンドの出力全体を貼ってもらうことってできそうですかね?たぶん全部貼ってもそんなに行数ないはずなので上限に引っかかるとかはなさそうな気がしますが

0Like

Comments

Your answer might help someone💌