admin管理员组文章数量:1431253
Once I started passing props from parent to child to child I have been getting this problem where the getQuestion
function only gets me the first letter typed, In addition in the input field nothing shows up.
Before when my code was just Parent to child it worked.
I want to know what exactly is going on because I have tried debugging by console logging and all I know is certain is that it only registers the first letter.
This question did not help because I have not misspelled onChange
.
Can't type in React input text field
App.js
class App extends Component {
constructor(props){
super(props);
this.getPostId = this.getPostId.bind(this);
this.getQuestion = this.getQuestion.bind(this);
this.makePost = this.makePost.bind(this);
this.getBody = this.getBody.bind(this);
this.getPostType = this.getPostType.bind(this);
this.getImgSrc = this.getImgSrc.bind(this);
this.submitPost = this.submitPost.bind(this);
this.formOpen = this.formOpen.bind(this);
this.formClose = this.formClose.bind(this);
this.back = this.back.bind(this);
this.showPost = this.showPost.bind(this);
this.renderPosts = this.renderPosts.bind(this);
//Answer/Response methods
this.makeAnswer = this.makeAnswer.bind(this);
this.getAnswer = this.getAnswer.bind(this);
this.submitAnswer = this.submitAnswer.bind(this);
this.state = {
posts: [],
answers: [],
question: '',
body: '',
postType: 'Question',
imgSrc: '',
form: false,
openedPost: null,
answer: '',
favorited: false,
//sign up
email:'',
password: '',
user: null
}
}
getQuestion(event) {
event.preventDefault();
this.setState({ question:event.target.value });
}
render() {
return (
<Router>
<div className="container">
<Route
exact path={"/"}
ponent={() => <Home />}
/>
<Route
exact path={"/home"}
ponent={() => <Home />}
/>
<Route
exact path={"/signup"}
ponent={() => <SignUp />}
/>
<Route
exact path={`/dashboard`}
ponent={() =>
<Dashboard back={this.back}
form={this.state.form}
openedPost={this.state.openedPost}
renderPosts={this.renderPosts}
formClose={this.formClose}
formOpen={this.formOpen}
posts={this.state.posts}
getPostId={this.getPostId}
getQuestion={this.getQuestion}
makePost={this.makePost}
getBody={this.getBody}
getPostType={this.getPostType}
getImgSrc={this.getImgSrc}
submitPost={this.submitPost}
test={this.test}
question={this.state.question}
/>}
/>
<Route
exact path={`/dashboard/post${this.state.openedPost}`}
ponent={() =>
<SinglePost posts={this.state.posts}
openedPost={this.state.openedPost}
getAnswer={this.getAnswer}
makeAnswer={this.makeAnswer}
submitAnswer={this.submitAnswer}
showAnswers={this.showAnswers}
renderAnswers={this.renderAnswers}
renderFavorite={this.renderFavorite}
userFavorited={this.userFavorited}
back={this.back}
/>
}
/>
</div>
</Router>
);
}
Dashboard.js
import React, { Component } from 'react';
import Navagationbar from '../../ponents/Navigation/Navagationbar';
import Header from '../../ponents/Header/Header';
import SignUpButton from '../../ponents/SignUp/SignUpButton';
import AddPostForm from './AddPostForm';
import './styles.css';
import {
Link
} from 'react-router-dom'
class Dashboard extends Component {
render() {
let renderedPosts = null;
let createPostButton = <div className="container" ><button className="button-primary" onClick={this.props.formOpen}> Create Post </button> </div>;
if(this.props.openedPost) {
renderedPosts = null;
createPostButton = null;
}
else {
renderedPosts = this.props.renderPosts();
}
let createPostForm = null;
const openedForm = this.props.form;
if(openedForm) {
createPostForm =
<AddPostForm
formClose={this.props.formClose}
posts={this.props.posts}
getPostId={this.props.getPostId}
getQuestion={this.props.getQuestion}
makePost={this.props.makePost}
getBody={this.props.getBody}
getPostType={this.props.getPostType}
getImgSrc={this.props.getImgSrc}
submitPost={this.props.submitPost}
question={this.props.question}
/>
createPostButton = null;
}
console.log("OPENED FORM IS " + openedForm)
return (
<div >
<SignUpButton />
<Header />
<button onClick={this.props.test}/>
{this.props.openedPost ? null : <Navagationbar />}
{createPostForm}
<div className="row">
<div>
{createPostButton}
</div>
</div>
<div className="row">
</div>
<div className="row">
<div className="twelve columns">
{renderedPosts}
</div>
</div>
</div>
);
}
}
export default Dashboard;
AddPostForm.js
import React, { Component } from 'react';
import './styles.css';
class AddPostForm extends Component {
render() {
return(
<div className="container">
<div className="row">
<div className="six columns">
<label>Post Title</label>
<input onChange={this.props.getQuestion} value={this.props.question} className="u-full-width" type="search" placeholder="title" id="exampleEmailInput"/>
</div>
<div className="six columns">
<label>Post Type</label>
<select value={this.props.type} onChange={this.props.getPostType} className="u-full-width">
<option value="Question">Question</option>
<option value="Discussion">Discussion</option>
</select>
</div>
</div>
<div className="row">
<div className="twelve columns">
<label>Post</label>
<textarea onChange={this.props.getBody} className="u-full-width" placeholder="get some clout" id="postMessage"></textarea>
<label>
<span>Image Link</span> <br />
<input type="search" onChange={this.props.getImgSrc}/>
</label>
<input className="button-primary" type="button" value="submit" onClick={this.props.submitPost}/>
<button onClick={this.props.formClose}>Cancel </button>
</div>
</div>
</div>
);
}
}
export default AddPostForm;
edit:
After removing event.preventDefault()
from getQuestion
I can type but why does the input field unfocus after typing a single letter.
Is it because after every time I type the input field re-renders?
edit: Added majority of the code as requested.
This is sufficient in my opinion let me know if you want the rest of the functions.
Once I started passing props from parent to child to child I have been getting this problem where the getQuestion
function only gets me the first letter typed, In addition in the input field nothing shows up.
Before when my code was just Parent to child it worked.
I want to know what exactly is going on because I have tried debugging by console logging and all I know is certain is that it only registers the first letter.
This question did not help because I have not misspelled onChange
.
Can't type in React input text field
App.js
class App extends Component {
constructor(props){
super(props);
this.getPostId = this.getPostId.bind(this);
this.getQuestion = this.getQuestion.bind(this);
this.makePost = this.makePost.bind(this);
this.getBody = this.getBody.bind(this);
this.getPostType = this.getPostType.bind(this);
this.getImgSrc = this.getImgSrc.bind(this);
this.submitPost = this.submitPost.bind(this);
this.formOpen = this.formOpen.bind(this);
this.formClose = this.formClose.bind(this);
this.back = this.back.bind(this);
this.showPost = this.showPost.bind(this);
this.renderPosts = this.renderPosts.bind(this);
//Answer/Response methods
this.makeAnswer = this.makeAnswer.bind(this);
this.getAnswer = this.getAnswer.bind(this);
this.submitAnswer = this.submitAnswer.bind(this);
this.state = {
posts: [],
answers: [],
question: '',
body: '',
postType: 'Question',
imgSrc: '',
form: false,
openedPost: null,
answer: '',
favorited: false,
//sign up
email:'',
password: '',
user: null
}
}
getQuestion(event) {
event.preventDefault();
this.setState({ question:event.target.value });
}
render() {
return (
<Router>
<div className="container">
<Route
exact path={"/"}
ponent={() => <Home />}
/>
<Route
exact path={"/home"}
ponent={() => <Home />}
/>
<Route
exact path={"/signup"}
ponent={() => <SignUp />}
/>
<Route
exact path={`/dashboard`}
ponent={() =>
<Dashboard back={this.back}
form={this.state.form}
openedPost={this.state.openedPost}
renderPosts={this.renderPosts}
formClose={this.formClose}
formOpen={this.formOpen}
posts={this.state.posts}
getPostId={this.getPostId}
getQuestion={this.getQuestion}
makePost={this.makePost}
getBody={this.getBody}
getPostType={this.getPostType}
getImgSrc={this.getImgSrc}
submitPost={this.submitPost}
test={this.test}
question={this.state.question}
/>}
/>
<Route
exact path={`/dashboard/post${this.state.openedPost}`}
ponent={() =>
<SinglePost posts={this.state.posts}
openedPost={this.state.openedPost}
getAnswer={this.getAnswer}
makeAnswer={this.makeAnswer}
submitAnswer={this.submitAnswer}
showAnswers={this.showAnswers}
renderAnswers={this.renderAnswers}
renderFavorite={this.renderFavorite}
userFavorited={this.userFavorited}
back={this.back}
/>
}
/>
</div>
</Router>
);
}
Dashboard.js
import React, { Component } from 'react';
import Navagationbar from '../../ponents/Navigation/Navagationbar';
import Header from '../../ponents/Header/Header';
import SignUpButton from '../../ponents/SignUp/SignUpButton';
import AddPostForm from './AddPostForm';
import './styles.css';
import {
Link
} from 'react-router-dom'
class Dashboard extends Component {
render() {
let renderedPosts = null;
let createPostButton = <div className="container" ><button className="button-primary" onClick={this.props.formOpen}> Create Post </button> </div>;
if(this.props.openedPost) {
renderedPosts = null;
createPostButton = null;
}
else {
renderedPosts = this.props.renderPosts();
}
let createPostForm = null;
const openedForm = this.props.form;
if(openedForm) {
createPostForm =
<AddPostForm
formClose={this.props.formClose}
posts={this.props.posts}
getPostId={this.props.getPostId}
getQuestion={this.props.getQuestion}
makePost={this.props.makePost}
getBody={this.props.getBody}
getPostType={this.props.getPostType}
getImgSrc={this.props.getImgSrc}
submitPost={this.props.submitPost}
question={this.props.question}
/>
createPostButton = null;
}
console.log("OPENED FORM IS " + openedForm)
return (
<div >
<SignUpButton />
<Header />
<button onClick={this.props.test}/>
{this.props.openedPost ? null : <Navagationbar />}
{createPostForm}
<div className="row">
<div>
{createPostButton}
</div>
</div>
<div className="row">
</div>
<div className="row">
<div className="twelve columns">
{renderedPosts}
</div>
</div>
</div>
);
}
}
export default Dashboard;
AddPostForm.js
import React, { Component } from 'react';
import './styles.css';
class AddPostForm extends Component {
render() {
return(
<div className="container">
<div className="row">
<div className="six columns">
<label>Post Title</label>
<input onChange={this.props.getQuestion} value={this.props.question} className="u-full-width" type="search" placeholder="title" id="exampleEmailInput"/>
</div>
<div className="six columns">
<label>Post Type</label>
<select value={this.props.type} onChange={this.props.getPostType} className="u-full-width">
<option value="Question">Question</option>
<option value="Discussion">Discussion</option>
</select>
</div>
</div>
<div className="row">
<div className="twelve columns">
<label>Post</label>
<textarea onChange={this.props.getBody} className="u-full-width" placeholder="get some clout" id="postMessage"></textarea>
<label>
<span>Image Link</span> <br />
<input type="search" onChange={this.props.getImgSrc}/>
</label>
<input className="button-primary" type="button" value="submit" onClick={this.props.submitPost}/>
<button onClick={this.props.formClose}>Cancel </button>
</div>
</div>
</div>
);
}
}
export default AddPostForm;
edit:
After removing event.preventDefault()
from getQuestion
I can type but why does the input field unfocus after typing a single letter.
Is it because after every time I type the input field re-renders?
edit: Added majority of the code as requested.
This is sufficient in my opinion let me know if you want the rest of the functions.
Share Improve this question edited Dec 18, 2017 at 1:20 codejockie 10.9k4 gold badges50 silver badges57 bronze badges asked Dec 17, 2017 at 17:13 OmarOmar 3,4213 gold badges24 silver badges41 bronze badges 9-
You're doing
event.preventDefault()
??! – Andrew Li Commented Dec 17, 2017 at 17:15 - okay, thats weird earlier that did not prevent me. That however does not fix it pletely. I think I need to focus the input because after typing a letter the user has to click on the input box again to type. Do you know why after typing one letter it unfocuses? @Li357 – Omar Commented Dec 17, 2017 at 17:18
-
Okay, theres a few questions I have seen on the react docs that i should maybe do
<input onChange={this.props.getQuestion} value={this.props.question}/>
question is just the string that I store the input in state in App.js. When I do that and take away event.prevent.default() I can type but the text unfocuses after every letter and the user has to click on it again. Now when I just remove event.preventDefault() with the code I have provided above does not allow me to type. @Li357 – Omar Commented Dec 17, 2017 at 17:24 - Please could you show full code to each file, I might be able to help. – codejockie Commented Dec 17, 2017 at 17:36
- @JohnKennedy added a majority of the code let me know if it is sufficient – Omar Commented Dec 17, 2017 at 17:48
3 Answers
Reset to default 3Having gone through the code, I noticed all methods e from the root level ponent App
. In which case when you type in the post title input field it immediately calls the parent getQuestion
method which set state there by causing a re-render of the page which in turn causing the input field to lose focus.
Method 1:
To fix this I'd suggest you maintain state for the AddPostForm
by allowing it manage its own state.
import React, { Component } from 'react';
class AddPostForm extends Component {
state = {
question: ""
}
setQuestion = (event) => {
this.setState({
question: event.target.value
});
}
render() {
return (
<div className="container">
<div className="row">
<div className="six columns">
<label>Post Title</label>
<input
onChange={this.setQuestion} // note change
value={this.state.question} // note change
className="u-full-width"
type="search"
placeholder="title"
id="exampleEmailInput"
/>
</div>
...
</div>
</div>
);
}
}
export default AddPostForm;
Method 2:
In App.js
render
method I made few changes that will allow you pass down props to the child ponents without the text fields loosing focus.
render() {
return (
<Router>
<div className="container">
<Route
exact
path="/"
ponent={Home}
/>
<Route
exact
path="/home"
ponent={Home}
/>
<Route
exact
path="/signup"
ponent={SignUp}
/>
<Route
exact
path="/dashboard"
render={(props) =>
<Dashboard
{...props}
back={this.back}
body={this.state.body}
form={this.state.form}
openedPost={this.state.openedPost}
renderPosts={this.renderPosts}
formClose={this.formClose}
formOpen={this.formOpen}
posts={this.state.posts}
getPostId={this.getPostId}
getQuestion={this.getQuestion}
makePost={this.makePost}
getBody={this.getBody}
getPostType={this.getPostType}
getImgSrc={this.getImgSrc}
submitPost={this.submitPost}
test={this.test}
question={this.state.question}
/>
}
/>
<Route
exact
path={`/dashboard/post${this.state.openedPost}`}
render={(props) =>
<SinglePost
{...props}
posts={this.state.posts}
openedPost={this.state.openedPost}
getAnswer={this.getAnswer}
makeAnswer={this.makeAnswer}
submitAnswer={this.submitAnswer}
showAnswers={this.showAnswers}
renderAnswers={this.renderAnswers}
renderFavorite={this.renderFavorite}
userFavorited={this.userFavorited}
back={this.back}
/>
}
/>
</div>
</Router>
);
}
In the Route
s for dashboard
I changed from using ponent
prop of Route
to using render
prop instead. This fixes the issue.
To improve it you can clear the form after the state data is send to the parent ponent.
handleChange(e) {
let { name, value } = e.target;
// clone current state
let clonedState = Object.assign({}, this.state);
clonedState.data[name] = value;
this.setState({
data: clonedState.data,
});
}
handleSubmit(e) {
e.preventDefault();
this.props.getQuestion(this.state.data)
// clear state data
this.setState({ data: {} });
}
It would be better to track changes in the ponent the user is actually typing in. Then onSubmit, call your getQuestion(this.state).
This would be in any form ponent a user is typing in.
handleChange(e) {
let { name, value } = e.target;
this.setState({
[name]: value,
});
}
handleSubmit(e) {
e.preventDefault();
this.props.getQuestion(this.state)
}
本文标签: javascripthow come eventtargetvalue is only capturing the first letter in string inputStack Overflow
版权声明:本文标题:javascript - how come event.target.value is only capturing the first letter in string input - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1745571481a2664074.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论