フックインタビューの質問に反応する

Reactのフックとは何ですか?

フックは、Reactv16.8で追加された新機能です。フックを使用すると、クラスコンポーネントを記述せずに、Reactのすべての機能を使用できます。たとえば、バージョン16.8より前では、コンポーネントの状態を管理するには、クラスコンポーネントが必要です。useStateフックを使用して、機能コンポーネントに状態を保存できるようになりました





Reactフックはクラスコンポーネント内で機能しますか?

番号。





Reactでフックが導入されたのはなぜですか?

フックを導入する理由の1つは、クラスコンポーネント内でthisキーワードを操作するのが難しいことでした適切に処理されない場合、これはわずかに異なる意味を持ちます。これにより、this.setState()やその他のイベントハンドラーのような文字列が壊れます。フックを使用することにより、機能コンポーネントを操作する際のこの複雑さを回避します。





クラスコンポーネントはあまりうまく機能せず、ホットリロードの信頼性も低くなります。これがフックを作成するもう1つの理由です。





もう1つの理由は、ステートフルBeanのロジックを再利用する特定の方法がないことです。 HOC(高次コンポーネント)およびRender Propsテンプレート(関数またはクロージャーを使用して親から子に小道具を渡す方法)はこの問題を解決しますが、クラスコンポーネントのコードをここで変更する必要があります。フックを使用すると、コンポーネントの階層を変更せずにステートフルロジックを共有できます。





, . , (fetch) componentDidMount() componentDidUpdate(). : componentDidMount() componentWillUnmount() . .





useState? ?

useState - , . 2 . - . - .





useState React





import React, {useState} from "react";
      
      



useState, :





const [currentStateValue, functionToUpdateState] = useState(initialStateValue);
      
      



useState

. , , .





class Counter extends Component {
    state = {
        count: 0,
    };

    incrementCount = () => {
        this.setState({
            count: this.state.count + 1,
        });
    };

    render() {
        return (
            <div>
            <button onClick={this.incrementCount}>Count: {this.state.count}</button>
        </div>
    	);
    }
}
      
      



, React.









import React, { useState } from "react";

function Counter() {
    const [count, setCount] = useState(0);

    return (
        <div>
            <button
                onClick={() => {
                    setCount(count + 1);
                }}
            >
                Count: {count}
            </button>
        </div>
    );
}
      
      



useState 2

. .





class Counter extends Component {
    state = { count: 0 };

    incrementCount = () => {
        this.setState((prevState) => {
            return {
                count: prevState.count + 1,
            };
        });
    };

    decrementCount = () => {
        this.setState((prevState) => {
            return {
                count: prevState.count - 1,
            };
        });
    };

    render() {
        return (
            <div>
                <strong>Count: {this.state.count}</strong>
                <button onClick={this.incrementCount}>Increment</button>
                <button onClick={this.decrementCount}>Decrement</button>
            </div>
        );
    }
}
      
      



, React.





.





, callback. callback- .





import React, { useState } from "react";

function Counter() {
    const [count, setCount] = useState(0);

    const incrementCount = () => {
        setCount((prevCount) => {
            return prevCount + 1;
        });
    };

    const decrementCount = () => {
        setCount((prevCount) => {
            return prevCount - 1;
        });
    };

    return (
        <div>
            <strong>Count: {count}</strong>
            <button onClick={incrementCount}>Increment</button>
            <button onClick={decrementCount}>Decrement</button>
        </div>
    );
}
      
      



useState 3

, , .





export class Profile extends Component {
    state = {
        name: "Backbencher",
        age: 23,
    };

    onNameChange = (e) => {
        this.setState({
            name: e.target.value,
        });
    };

    onAgeChange = (e) => {
        this.setState({
            age: e.target.value,
        });
    };

    render() {
        return (
            <div>
                <form>
                    <input
                        type="text"
                        value={this.state.name}
                        onChange={this.onNameChange}
                    />
                    <input
                        type="number"
                        value={this.state.age}
                        onChange={this.onAgeChange}
                    />
                    <h2>
                        Name: {this.state.name}, Age: {this.state.age}
                    </h2>
                </form>
            </div>
        );
    }
}
      
      



, React.









import React, { useState } from "react";

function Profile() {
    const [profile, setProfile] = useState({
        name: "Backbencher",
        age: 23,
    });

    const onNameChange = (e) => {
        setProfile({ ...profile, name: e.target.value });
    };

    const onAgeChange = (e) => {
        setProfile({ ...profile, age: e.target.value });
    };

    return (
        <div>
            <form>
                <input type="text" value={profile.name} onChange={onNameChange} />
                <input type="text" value={profile.age} onChange={onAgeChange} />
                <h2>
                    Name: {profile.name}, Age: {profile.age}
                </h2>
            </form>
        </div>
    );
}
      
      



useState() , . setState() .





spread JavaScript.





?

setState() . , , , , , .





, setState() . useState() spread .





useEffect?

useEffect . . .





useEffect

, Boom , .





export class Banner extends Component {
    state = {
        count: 0,
    };

    updateState = () => {
        this.setState({
            count: this.state.count + 1,
        });
    };

    componentDidMount() {
        console.log("Boom");
    }

    componentDidUpdate() {
        console.log("Boom");
    }

    render() {
        return (
            <div>
                <button onClick={this.updateState}>State: {this.state.count}</button>
            </div>
        );
    }
}
      
      



console.log React.





.





componentDidMount() componentDidUpdate() - . useEffect. useEffect - , callback. callback , .





:





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

function Banner() {
    const [count, setCount] = useState(0);

    useEffect(() => {
        console.log("Boom");
    });

    const updateState = () => {
        setCount(count + 1);
    };

    return (
        <div>
            <button onClick={updateState}>State: {count}</button>
        </div>
    );
}
      
      



useEffect 2

:





function Banner() {
    const [count, setCount] = useState(0);
    const [name, setName] = useState("");

    useEffect(() => {
        console.log(" ");
    });

    return (
        <div>
            <button onClick={() => setCount(count + 1)}>State: {count}</button>
            <input
                type="text"
                value={name}
                onChange={(e) => setName(e.target.value)}
            />
        </div>
    );
}
      
      



« » . ?





.





useEffect , . props , . , , , . count .





useEffect:





useEffect(() => {
    console.log("Count is updated");
}, [count]);
      
      



useEffect 3

, . componentDidMount() .





export class Clock extends Component {
    state = {
        date: new Date(),
    };

    componentDidMount() {
        setInterval(() => {
            this.setState({
                date: new Date(),
            });
        }, 1000);
    }

    render() {
        return <div>{this.state.date.toString()}</div>;
    }
}
      
      



React.





.





componentDidMount() - , . useEffect, componentDidMount(). useEffect props . , - useState. . , React props, . , useEffect , componentDidMount().





React.





function Clock() {
    const [date, setDate] = useState(new Date());

    useEffect(() => {
        setInterval(() => {
            setDate(new Date());
        }, 1000);
    }, []);

    return <div>{date.toString()}</div>;
}
      
      



useEffect 4

, .





componentDidMount() {
    window.addEventListener("mousemove", this.handleMousePosition);
}

componentWillUnmount() {
    window.removeEventListener("mousemove", this.handleMousePosition);
}
      
      



このコードをReactフックのスタイルで書き直します。





決定。





useEffectフックでcomponentWillUnmount()ライフサイクルメソッドの機能を使用するには、コンポーネントがアンマウントされたときに実行する必要があるコードを含むコールバックを返す必要があります。





useEffect(() => {
    window.addEventListener("mousemove", handleMousePosition);

    return () => {
        window.removeEventListener("mousemove", handleMousePosition);
    }
}, []);
      
      



useContextを使用するタスク

これは、Context.Consumerコンポーネントのコードスニペットです。





import { NameContext, AgeContext } from "./ProviderComponent";

export class ConsumerComponent extends Component {
    render() {
        return (
            <NameContext.Consumer>
                {(name) => {
                    return (
                        <AgeContext.Consumer>
                            {(age) => (
                                <div>
                                    Name: {name}, Age: {age}
                                </div>
                            )}
                        </AgeContext.Consumer>
                    );
                }}
            </NameContext.Consumer>
        );
    }
}
      
      



useContext フックを使用しConsumerComponentを 書き直します。





解決策





フックは、機能コンポーネントでのみ使用できます。





ConsumerComponentは次のように書き直すことができます。





function ConsumerComponent() {
    const name = useContext(NameContext);
    const age = useContext(AgeContext);

    return (
        <div>
            Name: {name}, Age: {age}
        </div>
    );
}
      
      










All Articles