简体   繁体   中英

How can i turn this React class component into a functional component?

I'm working on implementing a braintree payment method in my react/mui app. I've found a way that works, but it's in a class component. How can I convert this info a proper functional component?

    const BraintreeDropInPaymentMethod = () => {
    class Store extends React.Component {
        instance;

        state = {
            clientToken: '<BRAIN TREE KEY>'
        };

        async componentDidMount() {
            const response = await fetch("server.test/client_token");
            const clientToken = await response.json();

            this.setState({
                clientToken,
            });
        }

        async buy() {
            const { nonce } = await this.instance.requestPaymentMethod();
            await fetch(`server.test/purchase/${nonce}`);
        }

        render() {
            if (!this.state.clientToken) {
                return (
                    <div>
                        <h1>Loading...</h1>
                    </div>
                );
            } else {
                return (
                    <div>
                        <DropIn
                            options={{ authorization: this.state.clientToken }}
                            onInstance={(instance) => (this.instance = instance)}
                        />
                        <Button
                            variant='contained'
                            onClick={this.buy.bind(this)}
                        >
                            Create Account
                        </Button>
                        <Button
                            variant='outlined'
                            sx={{ marginLeft: 3 }}
                            color='warning'
                            onClick={(e) => handleCancelAccountCreation(e)}
                            href='/store-front'
                        >
                            Cancel
                        </Button>
                    </div>
                );
            }
        }
    }

    const [user, setUser] = useState({})
    const handleCancelAccountCreation = (event) => {
        setUser({})
        document.getElementById('signInBtn').hidden = false
    }

    return (
        <Store/>
    )
}

this is my attempt, but I'm coming up short on how I should handle componentDidMount() . I know how to handle useState in some situations, except for this one. Also, how can I handle the 'instance' section in a functional format? thanks.

    const BraintreeDropInPaymentMethod = () => {

    const [token, setToken] = useState('<BRAIN TREE KEY>')
    const [user, setUser] = useState({})

    const contactServer = async () => {
        const res = await fetch('server.test/client_token')
        const clientToken = await res.json()
        console.log(clientToken)
        setToken(token)
    }

    const buy = async () => {
        const { nonce } = await this.instance.requestPaymentMethod()
        await fetch(`server.test/purchase/${nonce}`)
    }

    const handleCancelAccountCreation = (event) => {
        setUser({})
        document.getElementById('signInBtn').hidden = false
    }

    const createAccountOptions = () => {
        if (!token) {
            return (
                <div>
                    <h1>Loading...</h1>
                </div>
            ) else {
                return (
                    <div>
                        <DropIn
                            options={ authorization: {setToken})
                            onInstance={(instance) => (this.instance = instance)}
                        />
                        <Button
                            variant="contained'
                            onClick={buy}
                        >
                         Create Account
                        </Button
                            variant='outlined'
                            sx={{ marginLeft: 3 }}
                            color='warning'
                            onClick={(e) => handleCancelAccountCreation(e)}
                            href='/store-front'
                        >
                        <Button>
                            Cancel
                        </Button>
                    </div>
                )
            }
        }
    }

    return(
        <>
            <createAccountOptions/>
        </>
    )   
}

The functional equivalent of componentDidMount() is the useEffect hook .

In this case you would change this:

    async componentDidMount() {
        const response = await fetch("server.test/client_token");
        const clientToken = await response.json();

        this.setState({
            clientToken,
        });
    }

Into something like this:

  useEffect(() => {
    fetchData();
  }, []);

  const fetchData = async () => {
    const response = await fetch("server.test/client_token");
    const clientToken = await response.json();
    setState((old) => clientToken);
  };

Using the useEffect hook with an empty array as a dependency makes the function in it only run once as the component mounts.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM