Subscribe/Unsubscribe 输入形式的电子邮件 REACT

Subscribe/Unsubscribe an email in input form REACT

我有任务要

所以,我已经完成了这个任务,但问题是我的表单没有处于取消订阅状态,它保持电子邮件不变,按钮也没有将其状态从取消订阅更改为订阅,但结果是,当电子邮件有效,它应该可以向服务器发送订阅获取请求,取消订阅中的按钮文本更改,表单显示为 none,但如果电子邮件无效,则按钮应该有订阅文本,没有获取请求的可能性和输入表单显示 block.Besides 这个,要存储在本地存储中的值,当页面刷新时它使表单保持原来的状态,如果是订阅则订阅的所有更改都是实际的,如果不是,则反之亦然。
我只使用 javascript 完成了这项任务,它的工作原理如下:
电子邮件无效:

有效电子邮件:

所以,问题是,我做错了什么?为什么只有 subscribe fetch 有效以及如何修复表单以产生请求的结果,我已经筋疲力尽了,三天我试图回答这个问题但我什么都不懂..请帮忙,提前致谢!

JoinUsSection 组件的形式为:

import { useState, useEffect } from "react"
import { sendSubscribe } from "../scripts/subscribeFetch"
import { validateEmail } from "../scripts/email-validator"
import { unsubscribeUser } from "../scripts/unsubscribeFetch"

const JoinUsSection = props => {
  const { placeholder } = props
  //Input div functions

  let isSubscribedd = localStorage.getItem('Email')                          //Function for setting display to none if the form is subscribed and display to block 
  //console.log(validateEmail(isSubscribedd))                                //if form is unsubscribed
  let validatedEmail = validateEmail(isSubscribedd)

  let setDisplay = ''
  if (validatedEmail === true) {
    setDisplay = 'none'
    localStorage.setItem('isSubscribed', 'true')
  } else if (validatedEmail === false) {
    setDisplay = 'block'
    localStorage.setItem('isSubscribed', 'false')
  }
  //-------------------------------------

  //Input type text Functions

  const [email, setEmail] = useState(() => {
    //reading data from localStorage
    const localEmail = localStorage.getItem('Email')
    const initialValue = localEmail
    if (localStorage.getItem('Email') !== null) {
      return initialValue
    } else {
      return placeholder
    }
  })

  useEffect(() => {
    //storing input email in localStorage
    const introducedEmail = email
    //console.log(introducedEmail)
    localStorage.setItem('Email', introducedEmail)
  }, [email])
  //------------------------------------------------------


  //Input type button Functions 

  const [isDisabled, setDisabled] = useState(false)
  const [isSubscribed, setSubscribe] = useState('Subscribe')

  let isFetching = false
  let isUsed = false

  let introducedEmail = email

  const submitClickButton = async () => {
    subscribeEmail(introducedEmail)   //change the button style and set in local storage isSubscribed to true
    sendSubscribe(introducedEmail)  //send subscribe fetch to the server

    // prevent additional requests upon clicking on "Subscribe" and "Unsubscribe".
    if (isFetching) return // do nothing if request already made
    isFetching = true
    disableBtn()
    const response = await fetchMock()  //eslint-disable-line
    isFetching = false
    enableBtn()

    isUsed = true

    if (validateEmail(introducedEmail) == false) {
      isUsed = false
    }
  }

  const fetchMock = () => {
    return new Promise(resolve => setTimeout(() => resolve('hello'), 2000))
  }


  const disableBtn = () => {
    // button.disabled = true
    // button.style.opacity = '0.5'
    setDisabled(true);
  }
  const enableBtn = () => {
    // button.disabled= false
    // button.style.opacity = '1'
    setDisabled(false);
  }

  const opacityValue = props.disabled ? 0.5 : 1;

  const undoClickButton = () => {
    unsubscribeEmail()
    isUsed = false
  }

  const changeButtonState = () => {
    isUsed ? undoClickButton() : submitClickButton()
  }

  const subscribe = () => {
    //  const subscribeBtn = document.getElementById('subscribeButton')
    setSubscribe('Unsubscribe')
    // document.getElementById('emailForm').style.display = 'none'
    localStorage.setItem('isSubscribed', 'true')
    console.log(isUsed)
    //document.getElementById('submit-info').value = ''
    introducedEmail = ''
  }

  const unsubscribe = () => {
    //const subscribeBtn = document.getElementById('subscribeButton')
    setSubscribe('Subscribe')
    //document.getElementById('emailForm').style.display = 'block'
    localStorage.setItem('isSubscribed', 'false')
    console.log(isUsed)
  }

  const subscribeEmail = (email) => {
    const isValidEmail = validateEmail(email)
    if (isValidEmail === true) {
      subscribe()
    } else if (isValidEmail === false) {
      unsubscribe()
    }
  }

  const unsubscribeEmail = () => {
    unsubscribe()
    unsubscribeUser()
    localStorage.removeItem('Email')
  }
  //--------------------------------------

  return (
    <>
      <section className='app-section app-section--image-program' id='programContainer'>
        <h2 className='program-title'>Join Our Program</h2>
        <h3 className='program-subtitle'>Sed do eiusmod tempor incididunt<br />ut labore et dolore magna aliqua</h3>
        <form className='submitFieldWrapper' id='form'>
          <div
            style={{
              display: setDisplay
            }}>
            <input
              className='form-input'
              id='submit-info'
              type='text'
              placeholder='Email'
              value={email}
              onChange={(e) => setEmail(e.target.value)}
            />
          </div>
          <input
            id='subscribeButton'
            className='app-section__button submit-btn'
            type='button'
            value={isSubscribed}
            style={{
              opacity: opacityValue
            }}
            onClick={() => changeButtonState()}
            disabled={isDisabled} />
        </form>
      </section>
    </>
  )
}

export default JoinUsSection

订阅获取请求,在不同的文件夹和文件中:

import { validateEmail } from './email-validator.js'

export const sendSubscribe = (emailInput) => {
  const isValidEmail = validateEmail(emailInput)
  if (isValidEmail === true) {
    sendData(emailInput)
  }
}

export const sendHttpRequest = (method, url, data) => {
  return fetch(url, {
    method: method,
    body: JSON.stringify(data),
    headers: data
      ? {
          'Content-Type': 'application/json'
        }
      : {}
  }).then(response => {
    if (response.status >= 400) {
      return response.json().then(errResData => {
        const error = new Error('Something went wrong!')
        error.data = errResData
        throw error
      })
    }
    return response.json()
  })
}

const sendData = (emailInput) => {
  sendHttpRequest('POST', '/subscribe', {
    email: emailInput
  }).then(responseData => {
    return responseData
  }).catch(err => {
    console.log(err, err.data)
    window.alert(err.data.error)
  })
}

电子邮件验证器,在不同的文件夹和文件中:

const VALID_EMAIL_ENDINGS = ['gmail.com', 'outlook.com', 'yandex.ru']

export const validateEmail = (email) => !!VALID_EMAIL_ENDINGS.some(v => email.includes(v))

export { VALID_EMAIL_ENDINGS as validEnding }

取消订阅获取请求,在不同的文件夹和文件中:

export const unsubscribeUser = () => {
  fetch('/unsubscribe', { method: 'POST' }).then(response => { console.log(response.status) })
}

App.js:

import './App.css';
import JoinUsSection from './components/JoinUsSection';

function App() {
  return (
    <JoinUsSection/>
  );
}

export default App;

所以,我设法完成了这项任务,这并不容易,但我走到了尽头。我使用反应钩子和本地存储来存储按钮的状态以维护页面刷新时的值以及我用钩子解决的按钮问题。 整个组件如下:

import { useState, useEffect } from "react"
import { sendSubscribe } from "../scripts/subscribeFetch"
import { validateEmail } from "../scripts/email-validator"
import { unsubscribeUser } from "../scripts/unsubscribeFetch"

const JoinUsSection = props => {
  const { placeholder } = props
  //Input div functions

  //let isSubscribedd = localStorage.getItem('Email')                          //Function for setting display to none if the form is subscribed and display to block 
  //console.log(validateEmail(isSubscribedd))                                //if form is unsubscribed
  // let validatedEmail = validateEmail(isSubscribedd)

  // let setDisplay = ''
  // if (isSubscribed = 'Unsubscribe') {
  //   setDisplay = 'none'
  //   //localStorage.setItem('isSubscribed', 'true')
  // } else if (isSubscribed ='Subscribe') {
  //   setDisplay = 'block'
  //   //localStorage.setItem('isSubscribed', 'false')
  // }
  //-------------------------------------

  //Input type text Functions

  const [email, setEmail] = useState(() => {
    //reading data from localStorage
    const localEmail = localStorage.getItem('Email')
    const initialValue = localEmail
    if (localStorage.getItem('Email') !== null) {
      return initialValue
    } else {
      return placeholder
    }
  })

  useEffect(() => {
    //storing input email in localStorage
    const introducedEmail = email
    //console.log(introducedEmail)
    localStorage.setItem('Email', introducedEmail)
  }, [email])
  //------------------------------------------------------


  //Input type button Functions 

  let [isDisabled, setDisabled] = useState(false)
  let [isSubscribed, setSubscribe] = useState('Subscribe')
  let [status, setStatus] = useState(false);
  let [displayMode, setDisplay] = useState('block')
  const [opacity, setOpacity] = useState(1);

  useEffect(() => {
    const buttonState = localStorage.getItem('Button state')
    if (buttonState) {
      setSubscribe(JSON.parse(buttonState))
    }
  }, [])

  useEffect(() => {
    const statusState = localStorage.getItem('isSubmited')
    if (statusState) {
      setStatus(JSON.parse(statusState))
    }
  }, [])

  useEffect(() => {
    const displayMode = localStorage.getItem('displayMode')
    if (displayMode) {
      setDisplay(JSON.parse(displayMode))
    }
  }, [])

  useEffect(() => {
    localStorage.setItem('Button state', JSON.stringify(isSubscribed))
    localStorage.setItem('isSubmited', JSON.stringify(status))
    localStorage.setItem('displayMode', JSON.stringify(displayMode))
  })

  // if (isSubscribed === 'Unsubscribe') {
  //   setDisplay('none')
  //   //localStorage.setItem('isSubscribed', 'true')
  // } else if (isSubscribed === 'Subscribe') {
  //   setDisplay('block')
  //   //localStorage.setItem('isSubscribed', 'false')
  // }

  // let isFetching = false
  //let isUsed = false

  let introducedEmail = email

  const submitClickButton = async () => {
    subscribeEmail(introducedEmail)   //change the button style and set in local storage isSubscribed to true
    sendSubscribe(introducedEmail)  //send subscribe fetch to the server

    // prevent additional requests upon clicking on "Subscribe" and "Unsubscribe".
    if (isDisabled) return // do nothing if request already made
    //setDisabled(true)
    disableBtn()
    const response = await fetchMock()  //eslint-disable-line
    // isFetching = false
    //setDisabled(false)
    enableBtn()

    setStatus(true)

    if (validateEmail(introducedEmail) == false) {
      setStatus(false)
    }
  }

  const fetchMock = () => {
    return new Promise(resolve => setTimeout(() => resolve('hello'), 2000))
  }


  const disableBtn = () => {
    // button.disabled = true
    // button.style.opacity = '0.5'
    setOpacity(0.5)
    setDisabled(true);
  }
  const enableBtn = () => {
    // button.disabled= false
    // button.style.opacity = '1'
    setOpacity(1)
    setDisabled(false);
  }

 //let opacityValue =1
 //props.disabled ? 0.5 : 1;

  const undoClickButton = () => {
    unsubscribeEmail()
    setStatus(false)
  }

  const changeButtonState = () => {
    status ? undoClickButton() : submitClickButton()
  }

  const subscribe = () => {
    //  const subscribeBtn = document.getElementById('subscribeButton')
    setSubscribe('Unsubscribe')
    // document.getElementById('emailForm').style.display = 'none'
    localStorage.setItem('isSubscribed', 'true')
    setDisplay('none')
    console.log(status)
    // setEmail('')
    //document.getElementById('submit-info').value = ''
    //localStorage.setItem('Email', '')
  }

  const unsubscribe = () => {
    //const subscribeBtn = document.getElementById('subscribeButton')
    setSubscribe('Subscribe')
    //document.getElementById('emailForm').style.display = 'block'
    localStorage.setItem('isSubscribed', 'false')
    setDisplay('block')
    console.log(status)
  }

  const subscribeEmail = (email) => {
    const isValidEmail = validateEmail(email)
    if (isValidEmail === true) {
      subscribe()
    } else if (isValidEmail === false) {
      unsubscribe()
    }
  }

  const unsubscribeEmail = () => {
    unsubscribe()
    unsubscribeUser()
    setEmail('')
    localStorage.removeItem('Email')
  }
  //--------------------------------------

  return (
    <>
    <main id='app-container'>
      <section className='app-section app-section--image-program' id='programContainer'>
        <h2 className='program-title'>Join Our Program</h2>
        <h3 className='program-subtitle'>Sed do eiusmod tempor incididunt<br />ut labore et dolore magna aliqua</h3>
        <form className='submitFieldWrapper' id='form'>
          <div
          className="form-wrapper"
          id="emailForm"
            style={{
              display: displayMode
            }}
            >
            <input
              className='form-input'
              id='submit-info'
              type='text'
              placeholder='Email'
              value={email}
              onChange={(e) => setEmail(e.target.value)}
            ></input>
          </div>
          <input
            id='subscribeButton'
            className='app-section__button submit-btn'
            type='button'
            value={isSubscribed}
            style={{
              opacity
            }}
            onClick={() => { changeButtonState() }}
            disabled={isDisabled} ></input>
        </form>
      </section>
      </main>
    </>
  )
}

export default JoinUsSection