javascript - 我正在尝试从最低级别组件的输入字段中捕获数据
问题描述
我的状态位于我的 APP 级别组件中,并且我正在尝试捕获放入我的表单组件中的数据。我正在使用钩子,但我无法弄清楚我做错了什么!
我尝试将状态置于表单级别,但它返回未定义,我的最终目标是将此数据发送到 firebase,并将其显示在我的应用程序另一个页面上的表格中。
应用程序
import React, { useState, createRef } from "react";
import { render } from "react-dom";
import Header from "./components/Header";
import About from "./components/About";
const App = () => {
const [date, setDate] = useState("");
const [name, setName] = useState("");
const [hours, setHours] = useState("");
const [description, setDescription] = useState("");
return (
<div>
<Header />
</div>
);
};
render(<App />, document.getElementById("root"));
**头/路由器组件
import React from "react";
import { render } from "react-dom";
import {
BrowserRouter as Router,
Switch,
Route,
NavLink,
Link
} from "react-router-dom";
import Home from "./pages/home/Home";
import Data from "./pages/data/Data";
import About from "./pages/about/About";
import Contact from "./pages/contact/Contact";
import "../style.css";
const Header = () => {
return (
<Router>
<div>
<nav className="navbar">
<NavLink className="link nav-item" to="/entry">
Time Entry
</NavLink>
<NavLink className="link nav-item" to="/data">
Data
</NavLink>
<NavLink className="link nav-item-right" to="/about">
About
</NavLink>
<NavLink className="link nav-item-right" to="/contact">
Contact
</NavLink>
</nav>
{/* A <Switch> looks through its children <Route>s and
renders the first one that matches the current URL. */}
<Switch>
<Route exact path="/entry" component={Home} />
<Route exact path="/data" component={Data} />
<Route exact path="/about" component={About} />
<Route exact path="/contact" component={Contact} />
</Switch>
</div>
</Router>
);
};
export default Header;
主页组件
import React, { Fragment } from "react";
import InputForm from "./Form";
const Home = props => {
return (
<Fragment>
<InputForm />
</Fragment>
);
};
export default Home;
表单组件
import React, { Fragment, useState, createRef } from "react";
import { Button, Form, FormGroup, Label, Input, FormText } from "reactstrap";
const InputForm = props => {
const dateEntry = createRef();
const nameEntry = createRef();
const hourEntry = createRef();
const descriptionEntry = createRef();
const handleClick = e => {
e.preventDefault();
setDate(dateEntry.current.value);
setName(nameEntry.current.value);
setHours(hourEntry.current.value);
setDescription(descriptionEntry.current.value);
// console.log(nameEntry.current.value);
};
return (
<Form className="data-entry">
<FormGroup className="form-entry-items">
<Label className="label">Date</Label>
<Input type="date" className="input" ref={dateEntry} />
</FormGroup>
<FormGroup className="form-entry-items">
<Label className="label">Lease Acconting Manager Name</Label>{" "}
<Input type="text" className="input" ref={nameEntry} />
</FormGroup>
<FormGroup className="form-entry-items">
<Label className="label">Hours Worked</Label>{" "}
<Input className="input" ref={hourEntry}/>
</FormGroup>
<FormGroup className="form-entry-items">
<Label className="label">Description</Label>{" "}
<Input type="textarea" className="input" ref={descriptionEntry}/>
</FormGroup>
<Button onClick={handleClick}>Submit</Button>
</Form>
);
};
export default InputForm;
解决方案
首先,您应该质疑为什么要使用仅由InputForm使用的值来设置APP的状态。如果您只是打算在InputForm中使用它们,您应该将您的状态移动到该组件。
也许只需在InputFormstate
内部设置而不是iof使用,这样您就可以在那里处理它们而无需进行钻孔或其他操作。createRef
import React, { Fragment, useState, createRef } from "react";
import { Button, Form, FormGroup, Label, Input, FormText } from "reactstrap";
const InputForm = props => {
const [date, setDate] = useState("");
const [name, setName] = useState("");
const [hours, setHours] = useState("");
const [description, setDescription] = useState("");
/* Im not sure How this works inside your component Input, but why dont just use a onChange?*/
const dateEntry = createRef();
const nameEntry = createRef();
const hourEntry = createRef();
const descriptionEntry = createRef();
const handleInput = ( e, type) => {
switch( type ){
case'name':
setName( e.target.value );
break;
case'date':
setDate( e.target.value );
break;
case'description':
setDescription( e.target.value );
break;
case'hours':
setHours( e.target.value );
break;
}
}
const handleClick = e => {
e.preventDefault();
//Just submit your data or something...
};
return (
<Form className="data-entry">
<FormGroup className="form-entry-items">
<Label className="label">Date</Label>
<Input type="date" className="input" ref={dateEntry} onChange={ e => {handleChange( e, 'date') } } />
</FormGroup>
<FormGroup className="form-entry-items">
<Label className="label">Lease Acconting Manager Name</Label>{" "}
<Input type="text" className="input" ref={nameEntry} onChange={ e => {handleChange( e, 'name' ) } } />
</FormGroup>
<FormGroup className="form-entry-items">
<Label className="label">Hours Worked</Label>{" "}
<Input className="input" ref={hourEntry} onChange={ e => {handleChange( e, 'hours') } }/>
</FormGroup>
<FormGroup className="form-entry-items">
<Label className="label">Description</Label>{" "}
<Input type="textarea" className="input" ref={descriptionEntry} onChange={ e => {handleChange( e, 'description') } }/>
</FormGroup>
<Button onClick={handleClick}>Submit</Button>
</Form>
);
};
export default InputForm;
如果您需要访问来自任何其他组件的值,请尝试使用上下文Form
实现相同的功能,并可能尝试为它们添加一些操作和减速器。
如果您需要更多信息,请查看: Context Docs, Reducer Docs
推荐阅读
- javascript - 返回选中和未选中的复选框值
- ios - 在 iPhone X(及更高版本)上启动与键盘大小相同的 UIDatePicker
- c - LTO 模式下用于 ARM 的 GCC 8 正在删除中断处理程序和弱功能 - 如何防止它?
- react-native - ScrollView 在没有 flex 时越过父元素,但不能用 flex 看到
- php - 仅来自 php 服务的 pgsql 服务的 Docker SQLSTATE[08006]
- elasticsearch - elasticsearch赋予不同领域和场景更多的权重
- c# - 什么是更好的做法:存储字符串或使用关系?
- arrays - 在 mongodb 中存储和更新时间序列数据的最佳实践
- javascript - 固定滚动上的行与其他行重叠
- asp.net - 如何在验证摘要上显示文本框标签名称