reactjs Includes()不工作,正在接收“无法接收未定义的属性(阅读”“includes”“)

hkmswyz6  于 2023-05-17  发布在  React
关注(0)|答案(1)|浏览(125)

我正在学习一个关于react的教程,并且正在创建一个登录页面。当用户完成写邮件时,我们调用onBlur()。正如你在第120行看到的,onBlur在第8行调用了emailReducer,在那里运行了includes()命令。
然而,当我在第11行和第14行使用include()命令时,我总是得到这个错误消息(如本文标题所示)。我console.logged了第11行中的action.瓦尔值,它确实存在。
我觉得这是个时间问题。有人知道如何解决这个问题吗?谢谢!

import React, { useState, useEffect, useReducer } from 'react';

import Card from '../UI/Card/Card';
import classes from './Login.module.css';
import Button from '../UI/Button/Button';

// made outside the component function: doesnt use any props defined inside the function
const emailReducer = (state, action) => {
  if (action.type === 'USER_INPUT') {
    console.log(action.val);
    return { value: action.val, isValid: action.val.includes('@') };
  }
  if (action.type === 'INPUT_BLUR') {
    return { value: state.value, isValid: action.value.includes('@') };
  }

  return { value: '', isValid: false };
};

const passwordReducer = (state, action) => {
  if (action.type === 'USER_INPUT') {
    return { value: action.val, isValid: action.val.trim().length > 6 };
  }
  if (action.type === 'INPUT_BLUR') {
    return { value: state.value, isValid: action.value.trim().length > 6 };
  }

  return { value: '', isValid: false };
}

const Login = (props) => {
  // const [enteredEmail, setEnteredEmail] = useState('');
  // const [emailIsValid, setEmailIsValid] = useState();
  // const [enteredPassword, setEnteredPassword] = useState('');
  // const [passwordIsValid, setPasswordIsValid] = useState();
  const [formIsValid, setFormIsValid] = useState(false);
  
  const [emailState, dispatchEmail] = useReducer(emailReducer, {
    value: '', 
    isValid: null,
  });

  const [passwordState, dispatchPassword] = useReducer(passwordReducer, {
    value: '', 
    isValid: null,
  })

  useEffect(() => {
    console.log('EFFECT RUNNING');

    return () => {
      console.log('EFFECT CLEANUP');
    };
  }, [])
  
  // useEffect(() => {
  //   // start the Timer
  //   const identifier = setTimeout(() => {
      // setFormIsValid(
      //   emailState.value.includes('@') && enteredPassword.trim().length > 6
      //   );  
  //       console.log('okay im pretty sure ur done');
  //   }, 500);
    
  //   // can return, but MUST be a function = Called a CLEAN UP function
  //   // clean up fucntions ALWAYS run first before all other code in UseEffect
  //   return () => {
  //     // reset the Timer IF change was made
  //     console.log('CLEAN UP FUNCTION: reset timer')
  //     clearTimeout(identifier);
  //   };
  // }, [enteredEmail, enteredPassword]);
  

  const emailChangeHandler = (event) => {
    dispatchEmail({ type: 'USER_INPUT', val: event.target.value});

    setFormIsValid(
      event.target.value.includes('@') && passwordState.isValid
      );  
  };

  const passwordChangeHandler = (event) => {
    dispatchPassword({ type: 'USER_INPUT', val: event.target.value});

    setFormIsValid(
      emailState.isValid && event.target.value.trim().length > 6
    );
  };

  const validateEmailHandler = () => {
    // setEmailIsValid(emailState.isValid);
    dispatchEmail({type: 'INPUT_BLUR'});
  };

  const validatePasswordHandler = () => {
    dispatchPassword({type: 'INPUT_BLUR'})
  };

  const submitHandler = (event) => {
    event.preventDefault();
    props.onLogin(emailState.value, passwordState.value);
  };

  return (
    <Card className={classes.login}>
      <form onSubmit={submitHandler}>
        <div
          className={`${classes.control} ${
            emailState.isValid === false ? classes.invalid : ''
          }`}
        >
          <label htmlFor="email">E-Mail</label>
          <input
            type="email"
            id="email"
            value={emailState.value}
            onChange={emailChangeHandler}
            onBlur={validateEmailHandler}
          />
        </div>
        <div
          className={`${classes.control} ${
            passwordState.isValid === false ? classes.invalid : ''
          }`}
        >
          <label htmlFor="password">Password</label>
          <input
            type="password"
            id="password"
            value={passwordState.value}
            onChange={passwordChangeHandler}
            onBlur={validatePasswordHandler}
          />
        </div>
        <div className={classes.actions}>
          <Button type="submit" className={classes.btn} disabled={!formIsValid}>
            Login
          </Button>
        </div>
      </form>
    </Card>
  );
};

export default Login;
83qze16e

83qze16e1#

分派的onBlur操作没有有效负载:

const validateEmailHandler = () => {
  dispatchEmail({ type: 'INPUT_BLUR' });
};

const validatePasswordHandler = () => {
  dispatchPassword({ type: 'INPUT_BLUR' });
};

但是reducer函数需要一个value payload属性:

const emailReducer = (state, action) => {
  if (action.type === 'USER_INPUT') {
    return { value: action.val, isValid: action.val.includes('@') };
  }
  if (action.type === 'INPUT_BLUR') {
    // action.value is undefined!!
    return { value: state.value, isValid: action.value.includes('@') };
  }

  return { value: '', isValid: false };
};

const passwordReducer = (state, action) => {
  if (action.type === 'USER_INPUT') {
    return { value: action.val, isValid: action.val.trim().length > 6 };
  }
  if (action.type === 'INPUT_BLUR') {
    // action.value is undefined!!
    return { value: state.value, isValid: action.value.trim().length > 6 };
  }

  return { value: '', isValid: false };
}

我怀疑您的意思是在留下输入时只验证现有状态,为此您应该引用state.value而不是action.value
示例:

const emailReducer = (state, action) => {
  if (action.type === "USER_INPUT") {
    console.log(action.value);
    return { value: action.value, isValid: action.value.includes("@") };
  }
  if (action.type === "INPUT_BLUR") {
    return { ...state, isValid: state.value.includes("@") };
  }

  return { value: "", isValid: false };
};

const passwordReducer = (state, action) => {
  if (action.type === "USER_INPUT") {
    return { value: action.value, isValid: action.value.trim().length > 6 };
  }
  if (action.type === "INPUT_BLUR") {
    return { ...state, isValid: state.value.trim().length > 6 };
  }

  return { value: "", isValid: false };
};

相关问题