简体   繁体   中英

How to convert React class component to functional component with hooks

I am creating a markdown previewer in Reactjs where the user types in the markdown in a textarea tag and the converted markdown displays in a div tag.Currently, the project is in a class component and I was wondering how to convert it to a functional component with hooks because it would be easier to implement in another project I have. I've looked around and I couldn't seem to find anything that would help me much, especially regarding how to convert the constructor. Any help would be appreciated!

 export default class App extends React.Component {
      constructor(props) {
        super(props);
        this.state = {
          markdown: "",
        };
      }
    
      updateMarkdown(markdown) {
        this.setState({ markdown });
      }
    
      render() {
        return (
          <div className="App">
            <div className="container">
              <div className="row mt-4">
                <div className="col text-center">
                  <h1>
                    {" "}
                    <Badge className="text-align-center" variant="light">
                      Markdown Previewer
                    </Badge>
                  </h1>
                </div>
              </div>
    
              <div className="row mt-4">
                <div className="col-md-6">
                  {" "}
                  <div className="col text-center">
                    <h4>
                      <Badge className="text-align-center" variant="secondary">
                        Markdown Input
                      </Badge>
                    </h4>
                  </div>
                  <div className="input" style={inputStyle}>
                    <textarea
                      className="input"
                      style={inputStyle}
                      value={this.state.markdown}
                      onChange={(e) => {
                        this.updateMarkdown(e.target.value);
                      }}
                    >
                    </textarea>
                  </div>
                </div>
    
                <div className="col-md-6">
                  {" "}
                  <div className="col text-center">
                    <h4>
                      <Badge className="text-align-center" variant="secondary">
                        Preview
                      </Badge>
                    </h4>
                  </div>
                  <div
                    style={outputStyle}
                    dangerouslySetInnerHTML={{
                      __html: marked(this.state.markdown),
                    }}
                  ></div>
                </div>
              </div>
            </div>
          </div>
        );
      }
    }

Something like this should work:

const App = () => {
  const [markdown, setMarkdown] = React.useState('')

  return (
    <div className="App">
      {...other html}
      <textarea
        value={markdown}
        onChange={(e) => setMarkdown(e.target.value)}
      </textarea>
      {...other html}
    </div>
  )
}

The biggest change here for you will be the react state hook . Hopefully, my example shows clearly how you'd convert class component state into a react hook. You can also move the onChange method into its own function above the return. Something like...

const [markdown, setMarkdown] = React.useState('')

const handleChange = (e) => setMarkdown(e.target.value)

return (...)
import React, { useState } from 'react';

export default function App(props) {
  const [markdown, setMarkDown] = useState("");
  const updateMarkdown = (markdown) => {
    setMarkDown(markdown);
  }

  return (
    <div className="App">
      <div className="container">
        <div className="row mt-4">
          <div className="col text-center">
            <h1>
              {" "}
              <Badge className="text-align-center" variant="light">
                Markdown Previewer
                </Badge>
            </h1>
          </div>
        </div>

        <div className="row mt-4">
          <div className="col-md-6">
            {" "}
            <div className="col text-center">
              <h4>
                <Badge className="text-align-center" variant="secondary">
                  Markdown Input
                  </Badge>
              </h4>
            </div>
            <div className="input" style={inputStyle}>
              <textarea
                className="input"
                style={inputStyle}
                value={markdown}
                onChange={(e) => {
                  updateMarkdown(e.target.value);
                }}
              >
              </textarea>
            </div>
          </div>

          <div className="col-md-6">
            {" "}
            <div className="col text-center">
              <h4>
                <Badge className="text-align-center" variant="secondary">
                  Preview
                  </Badge>
              </h4>
            </div>
            <div
              style={outputStyle}
              dangerouslySetInnerHTML={{
                __html: marked(markdown),
              }}
            ></div>
          </div>
        </div>
      </div>
    </div>
  )
}

What I have done here is:

  1. Replaced class with a function
  2. Removed constructor
  3. Class methods won't work inside a function, so converted them all to functions(closures).
  4. Used React hooks (useState)

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