简体   繁体   中英

React: How to add onChange functionality inside of Function component using React Hooks? Need onClick event from a checkbox to influence input state

I have a function component with a checkbox and an input. I'm trying to create an onChange function for the checkbox that clears the input and disables it whenever a user clicks it by implementing the useState React Hook. Does anyone have any experience with Hooks who's done something like this before? I'm trying to look at code samples to better wrap my head around this as I'm still new to React Hooks

import React from 'react'
import PropTypes from 'prop-types'
import styled from 'styled-components'
import {
  Col, Row, Icon, Input, Tooltip
} from 'antd'
import Checkbox from '../elements/Checkbox'

const CustomerDetails = ({ customer }) => {
  if (customer === null) {
    return (
      <Container>
        <Row>
          <Col span={24}>
            <ErrorContainer>
              <Icon type="exclamation-circle" />
            </ErrorContainer>
          </Col>
        </Row>
      </Container>
    )
  }

  return (
    <Container>
      <h2>{customer.contact.name}</h2>
      <Row>
        <Col span={8}>
          <H3>
            <strong>Primary Contact:</strong>
          </H3>
          <P>{customer.contact.name}</P>
          <P>{customer.contact.phone}</P>
        </Col>
        <Col span={8}>
          <H3>
            <strong>Service Address:</strong>
          </H3>
          <P>{customer.site.address1}</P>
          <P>{customer.site.address2}</P>
          <P>
            {customer.site.city},&nbsp;{customer.site.state}&nbsp;
            {customer.site.postalCode}
          </P>
        </Col>
        <Col span={8}>
          <H3>
            <strong>Billing Address:</strong>
          </H3>
          <P>{customer.account.billingStreet}</P>
          <P>
            {customer.account.billingCity},&nbsp;{customer.account.billingState}
            &nbsp;
            {customer.account.billingPostalCode}
          </P>
        </Col>
      </Row>
      <br />
      <Row>
        <Col span={10}>
          <h4>
            PRIMARY CONTACT EMAIL &nbsp;
            <Tooltip
              placement="topRight"
              title={primaryContact}
            >
              <StyledTooltipIcon
                type="question-circle"
                theme="filled"
              />
            </Tooltip>
          </h4>
        </Col>
      </Row>
      <Row>
        <Col span={8}>
          <StyledInput value={customer.contact.email} />
        </Col>
        <Col span={2} />
        <Col span={8}>
          <StyledCheckbox /> EMAIL OPT OUT{' '}
          <Tooltip
            placement="topRight"
            title={emailText}
          >
            <StyledTooltipIcon
              type="question-circle"
              theme="filled"
            />
          </Tooltip>
        </Col>
      </Row>
    </Container>
  )
}

CustomerDetails.propTypes = {
  customer: PropTypes.object
}

CustomerDetails.defaultProps = {
  customer: {}
}

const Container = styled.div`
  text-align: left;
`
const StyledCheckbox = styled(Checkbox)`
  input + span {
    border-radius: 0px;
    width: 35px;
    height: 35px;
    border: 2px solid ${({ theme }) => theme.colors.black};
    background-color: transparent;
    color: ${({ theme }) => theme.colors.black};
    border-color: ${({ theme }) => theme.colors.black};
    transition: none;
  }

  input:checked + span {
    border: 2px solid ${({ theme }) => theme.colors.black};
    width: 30px;
    height: 30px;
  }

  input + span:after {
    border-color: ${({ theme }) => theme.colors.black};
    left: 20%;
    transition: none;
    width: 12.5px;
    height: 20px;
  }

  input:disabled + span:after {
    border-color: ${({ theme }) => theme.colors.gray};
  }

  input:not(:checked):hover + span:after {
    border-color: ${({ theme }) => theme.colors.gray};
    opacity: 1;
    transform: rotate(45deg) scale(1) translate(-50%, -50%);
  }

  input:focus + span {
    border-color: ${({ theme }) => theme.colors.primary};
  }
`

const StyledInput = styled(Input)`
  max-width: 100%;

  &&& {
    border: 2px solid ${({ theme }) => theme.colors.black};
    border-radius: 0px;
    height: 35px;
  }
`

const ErrorContainer = styled.div`
  /* margin-left: 25%; */
`

const StyledTooltipIcon = styled(Icon)`
  color: #1571da;
`

const H3 = styled.h3`
  white-space: nowrap;
  margin-top: 0;
  margin-bottom: 0;
  line-height: 1.5;
}
`

const H4 = styled.h4`
  text-decoration: underline;
  color: #1590ff;
`

const P = styled.p`
  margin-top: 0;
  margin-bottom: 0;
  font-size: 1rem;
`

export default CustomerDetails

You can use the useState hook to create a state variable that tracks whether the user has clicked the checkbox to disable the other input. The useState hook is a function that takes an initial value and returns a state variable and a function used to update the value of that state variable (which works pretty much the same as setState but only for a single state variable).

For example:

const [x, setX] = React.useState(1); // `x` is initially 1, but that will change on later renders

setX(prevX => prevX + 1); // increments `x` for the next render;

You'll also need to create an event handler function to respond to the clicking of this checkbox.

Here is a full example:

import React from "react";

const MyComponent = props => {
    const [disableInputIsChecked, setDisableInputIsChecked] = React.useState(false);
    const [inputValue, setInputValue] = React.useState("");

    function clearInput() {
        setInputValue("");
    }

    function handleInputChange(event) {
        setInputValue(event.target.value);
    }

    function handleCheckboxClick(event) {
        if (!disableInputIsChecked) { // this click was to check the box
            clearInput();
        }
        setDisableInputIsChecked(prevValue => !prevValue); // invert value
    }

    return (
        <form>
            <input type="checkbox" value={ disableInputIsChecked } onChange={ handleCheckboxClick }/>
            <input type="text" value={ inputValue } onChange={ handleInputChange } disabled={ disableInputIsChecked }/>
        </form>
    )
}

Here's a working example .

Probably you'll want to come up with better names for these values, but hopefully you get the point here.

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