首页 > 解决方案 > React 从多个输入文本字段中读取输入值

问题描述

嗨,我有一个使用 imgflip 公共 api 的小表情包编辑器。我通常使用 Angular 进行开发,但我正在尝试学习反应,所以我现在有点迷茫。

在我的项目中,当我加载页面时,我会得到一份所有可用 meme 模板的列表,然后当您选择一个模板时,您会拥有该模板和每个 meme 文本行的一个文本字段。每个模板上输入文本的数量都会发生变化,这就是我卡住的地方。

这个想法是获取所有输入文本值,将其发送到 api 并将生成的 meme 显示给用户。

这是我现在的代码:

应用程序.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;

编辑器.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;

我对渲染输入文本字段的 TextBox 函数并不感到自豪,但现在我最关心的是如何让它工作。

我被卡住的地方在 Editor.js 上,我需要在编辑器上的输入文本字段中获取所有文本,以将其发送到 API。在我遵循的其他教程中,我使用应用程序的状态使用 onChange 事件进行了操作,因此当用户在文本提交上键入时,状态会更新,当单击提交按钮时,我只使用当前状态,但在这种情况下我没有因为有多个不同的输入,所以看不到它的可能。

顺便说一下,这是我正在使用的 API:https ://imgflip.com/api

标签: javascriptreactjsapiinput

解决方案


首先,您需要跟踪输入中的值,方法是向 中添加一个数组TextBox 并使输入受控。

其次,您需要将值传递给父级。为此,您可以添加一个处理程序方法,该方法会将值记住到 aref中,例如

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

handleChange然后你作为一个道具传递并在之后调用它setValues。在提交时,您将拥有自己的价值观values.current

完整的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)
}

推荐阅读