React Hooks-动态呈现文本输入并将输入存储为一个数组

时间:2019-09-07 07:16:06

标签: arrays reactjs mongodb mongoose react-hooks

我有一个看起来像这样的用户模型:

{
    "name": "Sun12",
    "role": "1",
    "email": "sun12@gmail.com",
    "password": "test123",
    "about": "This is a description of me.",
    "skills": ["Acting", "Music", "Art", "English Literature"],
    "studying": "Mind Control"
}

我想创建一个将捕获上述用户信息的表单。

用户架构中的skills字段任意长-我希望用户能够添加任意数量的技能。

如何动态呈现文本输入字段,并将每个输入动态发送到skills数组?

这是我的整个Signup.js文件:

// users Signin

import React, {useState} from 'react';
import Layout from '../core/Layout';
import {API} from '../config';

const Signup = () => {

  const [values, setValues] = useState({
    name: '',
    email: '',
    password: '',
    studying: '',
    skills: [],
    error: '',
    success: ''
  });

  const {name, email, password, studying} = values;


  const signup = (user) => {
    fetch(`${API}/signup`, {
      method: "POST",
      headers: {
        Accept: 'application/json',
        "Content-Type": "application/json"
      },
      body: JSON.stringify(user)
    })
    .then(response => {
      return response.json();
    })
    .catch(err => {
      console.log(err);
    });
  };

  const clickSubmit = event => {
    event.preventDefault();
    signup({name, email, password, studying});
  };

  const handleChange = name => event => {
    setValues({...values, error: false, [name]: event.target.value});
  };



  const signUpForm = () => (
    <form>
        <div className="form-group">
            <label className="text-muted">Name</label>
            <input onChange={handleChange('name')} type="text" className ="form-control" />
        </div>

        <div className="form-group">
            <label className="text-muted">Email</label>
            <input onChange={handleChange('email')} type="email" className ="form-control" />
        </div>

        <div className="form-group">
            <label className="text-muted">Password</label>
            <input onChange={handleChange('password')} type="password" className="form-control" />
        </div>

        <div className="form-group">
            <label className="text-muted">Studying</label>
            <input onChange={handleChange('studying')} type="text" className ="form-control" />
        </div>

        <div>
            <div>{createInputs()}</div>
            <button onClick={addSkill}>Add</button>
        </div>

        <button onClick={clickSubmit} className="btn btn-primary">
          Sign Up
        </button>

    </form>
  );


  return(
  <Layout 
    title="Signup" 
    description="Join today."
    className="container col-md-8 offset-md-2">
      {signUpForm()}
      {JSON.stringify(values)}
  </Layout>
  );
};

export default Signup;

1 个答案:

答案 0 :(得分:2)

您只需要使用.map()遍历数组即可呈现与每种技能相对应的输入。然后设置一些事件处理程序,使您可以通过将另一个项目添加到数组中来更新该技能并创建新技能。

查看有效的沙箱:https://codesandbox.io/s/festive-bhaskara-gdxwm

import React, { useState, useEffect } from "react";

const User = ({ data }) => {
  const [user, setUser] = useState({
    name: "",
    role: "",
    email: "",
    password: "",
    about: "",
    skills: [],
    studying: ""
  });

  const createInputs = () => {
    return user.skills.map((skill, idx) => {
      return (
        <div>
          <input value={skill} onChange={e => updateSkill(e, idx)} />
        </div>
      );
    });
  };

  const updateSkill = (e, index) => {
    const userCopy = { ...user };
    userCopy.skills[index] = e.target.value;
    setUser(userCopy);
  };

  const removeSkill = index => {
    const userCopy = { ...user };
    const userCopySkills = [...userCopy.skills];

    userCopySkills.splice(index, 1);

    setUser({
      ...userCopy,
      skills: [...userCopySkills]
    });
  };

  const addSkill = () => {
    setUser(prevState => {
      return {
        ...prevState.user,
        skills: [...prevState.skills, ""]
      };
    });
  };

  useEffect(() => {
    console.log(user);
  }, [user]);

  return (
    <div>
      <div>{createInputs()}</div>
      <button onClick={addSkill}>Add</button>
    </div>
  );
};

export default User;

我把useEffect()扔到那里只是为了向您展示技能数组正在更新。您可以根据需要将其取下。