简体   繁体   English

React 从多个输入文本字段中读取输入值

[英]React read input values from multiple input text fields

Hi I have a little meme editor using the imgflip public api.嗨,我有一个使用 imgflip public api 的小模因编辑器。 I usually develop using Angular but I'm trying to learn react so I'm a little lost right now.我通常使用 Angular 进行开发,但我正在尝试学习反应,所以我现在有点迷茫。

On my project when I load the page I get a list of all the meme templates available, then when you select one template you have the template and one text field for each meme text line.在我的项目中,当我加载页面时,我得到了所有可用 meme 模板的列表,然后当您使用 select 一个模板时,您将拥有每个 meme 文本行的模板和一个文本字段。 The number of input texts changes on each template this is where I'm stuck.每个模板上输入文本的数量都会发生变化,这就是我卡住的地方。

The idea is to get all the input text values, send it to the api and show the generated meme to the user.这个想法是获取所有输入文本值,将其发送到 api 并向用户显示生成的 meme。

This is my code right now:这是我现在的代码:

App.js应用程序.js

import { useEffect, useState } from 'react';
import {
  BrowserRouter as Router,
  Switch,
  Route,
  Link
} from "react-router-dom";
import memeService from './services/memeService';
import Meme from './components/Meme';
import './App.css';
import Editor from './components/Editor';


function App() {

  const [memes, setMemes] = useState([]);

  useEffect(() => {
    (async function getData() {
      await getMemes();
    })();
  }, []);

  const getMemes = async () => {
    const results = await memeService.getMemes();
    setMemes(results.data.data.memes);
  }

  return (
    <>
      <Router>
        <Switch>
        <Route path="/:id/edit" children={<Editor />} />
          <Route path="/">
            <div className='container'>
              {memes.map(meme => <Meme key={meme.id} meme={meme} />)}
            </div>
          </Route>
        </Switch>
        
      </Router>
      
    </>
  )
}

export default App;

Editor.js编辑器.js

import { useEffect, useState } from "react";
import { useParams } from "react-router-dom";
import memeService from './../services/memeService';

const Editor = () => {

    const [meme, setMeme] = useState({});
    const {id } = useParams()

    const getMeme = async () => {
        setMeme(await memeService.getMeme(id));
    }

    useEffect(getMeme, [id]);

    const TextBox = () => {

        const inputs = [];

        for(let i = 0; i < meme.box_count; i++){
            inputs.push(<input key={i} type='text' />);
        }

        return (
            <>
                {inputs.map(input => {return input})}
            </>
        )
    }

    const generateMeme = () => {
        console.log('generating meme');
    }

    return (
        <>
            <div className='container'>
                <div className='meme'>
                    <img alt={meme.name} src={meme.url} />
                </div>
                <div className='text'>
                    <TextBox />
                </div>
            </div>
            <button onClick={generateMeme}>Save</button>
        </>
    )

}

export default Editor;

I'm not proud at all of the TextBox function that renders the input text fields but for now I'm mostly concerned about making this work.我对渲染输入文本字段的 TextBox function 并不感到自豪,但现在我最关心的是如何使这项工作正常进行。

THe point where I'm stuck is on the Editor.js I need to get all the text on the input text field that I have on the editor to send it to the API.我被卡住的地方在 Editor.js 上,我需要在编辑器上的输入文本字段中获取所有文本,以将其发送到 API。 On other tutorials that I followed I didi it using the app's state using the onChange event so when the user types on the text submit the states gets updated and when clicking on the submit button I just use the current state but on this scenario I don't see it possible as there's multiple and different inputs.在我遵循的其他教程中,我使用应用程序的 state 使用 onChange 事件进行了操作,因此当用户在文本上键入提交时,状态得到更新,当单击提交按钮时,我只使用当前的 state 但在这种情况下我不因为有多个不同的输入,所以看不到它的可能。

By the way this is the API I'm using: https://imgflip.com/api顺便说一句,这是我正在使用的 API: https://imgflip.com/api

First, you need to keep track of values in the inputs, by add an array to the TextBox and making inputs controlled.首先,您需要跟踪输入中的值,方法是向TextBox添加一个数组并控制输入。

Second, you need to pass the values to the parent.其次,您需要将值传递给父级。 For that you can add a handler method, which will remember the values into a ref , like为此,您可以添加一个处理程序方法,该方法会将值记住到ref中,例如

const values = useRef()
handleChange(newValues){
   values.current(newValues)
}

Then you pass handleChange as a prop and call it after setValues .然后您将handleChange作为道具传递并在setValues之后调用它。 And on submit you'll have your values in values.current在提交时,您将在values.current中获得您的值

The complete TextBox :完整的TextBox

const TextBox = (props) => {
const [values, setValues] = useState([])
const inputs = [];

useEffect(()=>{
  props.onChange && props.onChange(values)
}, [values])

function handleInput(e, i)
{
  setValues(v =>{
    const temp=[...v];
    temp[i]=e.target.value;
    return temp})
}

for(let i = 0; i < meme.box_count; i++){
  inputs.push(<input key={i} type='text' value={values[i]} onChange={(e) => handleInput(e,i) } />);
}

return (inputs)
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM