Need help translating into an arrow function

Viewed 83

I have this so far but need it in an arrow function on an existing form that is using react-hook-form and gatsby-plugin-intl

The form should be in the format below where I am also using useState for submission.

The code is checking for the value of the option selected to display a conditional field / I think I will need to use the watch API for this field, but first need to include the into the complete form.

   const ContactForm = ({ intl }) => {
   
   const [submitted, setSubmitted] = useState(false)
   
   [...]     }

As opposed to


https://codesandbox.io/s/cocky-oskar-o2m6c
   
   class SelectOptions extends React.Component {
     constructor(props) {
       super(props)
       this.state = {
         fruit: 'Apple',
       }
       this.handleChange = this.handleChange.bind(this)
     }
     handleChange(e) {
       this.setState({ fruit: e.target.value })
     }
   
     render() {
       const isComplaint = this.state.fruit
       let complaint
       if (isComplaint === 'Strawberry') {
         complaint = <div>How Are You Doing?</div>
       } else {
         complaint = <div></div>
       }
       return (
         <div className='mt-10'>
           SELECT ONE
           <div className='mt-2'>
             <select value={this.state.fruit} onChange={this.handleChange}>
               <option value='apple'>Apple</option>
               <option value='Strawberry'>Strawberry</option>
               <option value='Cucumber'>Cucumber</option>
             </select>
           </div>
           {complaint}
         </div>
       )
     }
   }
   export default SelectOptions
3 Answers

In react functional component you need useState from react to make a state. It's different than class component based. You can follow my code here. I have test it and works. Hopefully work for you to.

import { useState } from "react";

const SelectOptions = () => {
  const [fruit, setFruit] = useState("apple");

  const handleChange = (e) => {
    setFruit(e.target.value);
    console.log(e.target.value);
  };

  const Complaint = (props) => {
    return (
      <div>{props.fruit === "Strawberry" ? "How Are You Doing?" : ""}</div>
    );
  };

  return (
    <div className="mt-10">
      SELECT ONE
      <div className="mt-2">
        <select value={fruit} onChange={handleChange}>
          <option value="apple">Apple</option>
          <option value="Strawberry">Strawberry</option>
          <option value="Cucumber">Cucumber</option>
        </select>
      </div>
      <Complaint fruit={fruit} />
    </div>
  );
};

export default SelectOptions;

In there i make Complaint as component separated. you can make it in different file if you want to, and than import that as usually.

I don't think it's the way to learn, you have fully detailed docs - https://reactjs.org/docs/hooks-intro.html

But anyway, if it helps - it should be something like -

const SelectOptions = (props) => {
    [state, setState] = useState({})

    const handleChange = (e) => {
        setState({...state, fruit: e.target.value})
    }

    return (
         ...
         <select value={state.fruit} onChange={handleChange}>
         ...
    )
}

General steps to convert class component to function component.

  1. Function components instanceless and therefore aren't "constructed". Convert this.state into one or more useState React hooks.
  2. Move componentDidMount, componentDidUpdate, and componentWillUnmount lifecycle method logic into one or more useEffect React hooks with appropriate dependency array.
  3. The entire function body of a function component is considered to be the "render" function. The function's return is what the render method returns.

Function component version:

const options = [
  {
    label: "Apple",
    value: "apple"
  },
  {
    label: "Strawberry",
    value: "strawberry"
  },
  {
    label: "Cucumber",
    value: "cucumber"
  }
];

const SelectOptions = () => {
  const [state, setState] = React.useState({ fruit: "Apple" });

  const handleChange = (e) => {
    // Functional state update to shallow merge any previous state
    setState((state) => ({
      ...state,
      fruit: e.target.value
    }));
  };

  return (
    <div className="mt-10">
      SELECT ONE
      <div className="mt-2">
        <select value={state.fruit} onChange={handleChange}>
          {options.map(({ label, value }) => (
            <option key={value} value={value}>
              {label}
            </option>
          ))}
        </select>
      </div>
      {/* Conditionally render the div */}
      {state.fruit === "strawberry" && <div>How Are You Doing?</div>}
    </div>
  );
};

Edit need-help-translating-into-an-arrow-function

Related