javascript - 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
解决方案
首先,您需要跟踪输入中的值,方法是向 中添加一个数组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)
}
推荐阅读
- css - 未找到此依赖项:
- javascript - 将所有点替换为单个
- jenkins - 詹金斯没有拿起 nuget 恢复的包
- scriban - Member Renamer 对性能有任何影响吗
- azure-service-fabric - 为什么服务结构不能在 Azure 门户中使用自动缩放功能进行缩放?
- node.js - 使用猫鼬更新对象中数组内的值
- perl - Perl中的子命令在由cron执行时不执行
- angular - 如何在Angular 6中一一验证输入字段
- python - 在更新时制作只读字段,但不在 ModelSerializer 的 CREATE 方法中
- ios - iOS - 禁用 Alamofire 缓存参数