I am passing a meteor collection as a prop in one of my components and trying to figure it out when do I actually receive props?
I tried accessing (for e.g. this.props.userData) the props in getInitialState is says undefined, then I tried accessing it in componentDidMount it says undefined, but in render method it works fine.
Which method before or after render can tell me that I have access to props? I want to initialize the state with the values props will have.
for example in the code below I get an error saying that userData is undefined.
getInitialState(){
return{
firstName : this.props.userData.firstName
}
}
Edit
So I am doing something like this, I am using props just to initialize the state variable.
export default React.createClass({
getInitialState(){
return {
email : this.props.user.email
}
},
onFormSubmit(event){
event.preventDefault();
},
onTextFieldChange(event){
switch (event.target.name) {
case "email":
this.setState({
email:event.target.value
});
break;
}
},
render() {
console.log(this.props.user.email);
return (
<div className="panel panel-default">
<div className="panel-heading">
<h3 className="panel-title text-center"><strong>Sign in with Existing Account</strong></h3>
</div>
<form className="form-horizontal" id="frmSignIn" role="form" onSubmit={this.onFormSubmit}>
<div className="modal-body">
<div className="form-group">
<label className="col-xs-4 control-label">Email</label>
<div className="col-xs-8">
<input type="email" id="email" name="email" className="form-control"
value={this.state.email}
onChange={this.onTextFieldChange}
placeholder="example#domain.com"
required/>
</div>
</div>
<div className="form-group">
<label className="col-xs-4 control-label">Password</label>
<div className="col-xs-8">
<input type="password" id="password" name="password" className="form-control"
placeholder="Password"
required/>
<label id="signin-error" className="error"> </label>
</div>
</div>
</div>
<div className="panel-footer">
<label className="col-xs-4 control-label"></label>
<div className="col-xs-8">
<input type="submit" className="btn btn-primary pull-right" value="SignIn"/>
</div>
</div>
</form>
</div>
);
}
});
The component receives the initial properties immediately on instantiation. Actually it is the first argument of the constructor:
class MyComp extends React.Component {
constructor (props) {
super(props)
// do something with props
}
componentWillReceiveProps (nextProps) {
// properties changed
}
}
In your case my best guess is that the parent component does not yet have your property ready. You can track the passed property by observing them in the constructor and in a componentWillReceiveProps(nextProps) function.
Meteor synchronises user data just like any other collection with the server. It means that initially Meteor.user() will return undefined, and your component doesn't receive the prop. Later when the user document is updated, your component's props are updated, too. You can catch this event by implementing function componentWillReceiveProps(newProps) {...}.
Related
I am working on a user registration/ log in page. I have two forms, a signUp form and a logIn form, and some state called signInState that determines which user form to display. I have two buttons that toggle the signInState, and if the signInState is true, I want it to display the log in form, if its false, I want to display the sign up form. The state is changing, but for some reason the conditional rendering is not working. Can someone help me figure out why my toggleSignInState doesn't change what's being rendered on the page? Thanks
Here is my react code for the signInPage itself
import React from 'react'
import SignUp from './SignUp'
import LogIn from './LogIn'
export default function SignInPage() {
const [signInState, setSignInState] = React.useState(true);
function toggleSignIn(event) {
console.log(event.target.id)
setSignInState(event.target.id);
/*setSignInState(event.target.value);*/
}
return (
<div className="signInPage">
<div className="signInPageFormContainer">
<p>{signInState}</p>
{!signInState && <SignUp /> }
{signInState && <LogIn /> }
<div className="signUpPageToggleContainer">
<button onClick={toggleSignIn} id='true'>Log In</button>
<button onClick={toggleSignIn} id='false'>Sign Up</button>
</div>
</div>
</div>
)
}
here is the code for the signUp form
import React from 'react'
export default function SignUp() {
return(
<form className="signUpForm">
<input
name="username"
type="text"
placeholder="Username"
className="signUpInput"
/>
<input
name="email"
type="text"
placeholder="Email"
className="signUpInput"
/>
<input
name="password"
type="text"
placeholder="Password"
className="signUpInput"
/>
<input
name="confirmPassword"
type="text"
placeholder="Confirm password"
className="signUpInput"
/>
<div>
<button>Sign Up</button>
<button>Cancel</button>
</div>
</form>
)
}
and here is the code for the log in form
import React from "react";
export default function LogIn() {
/*functions for log in procedure*/
return (
<form className="logInForm">
<input
placeholder="Username"
name="username"
type="text"
id="username"
className="logInFormInput"
/>
<input
placeholder="Password"
name="password"
type="text"
id="password"
className="logInFormInput"
/>
<div className="logInFormButtonContainer">
<button className="logInFormButton">Log In</button>
<button className="logInFormButton">Cancel</button>
</div>
</form>
)
}
Element attributes are strings. The string 'true' is not the same as the boolean true, and the string 'false' is not the same as the boolean false. Both 'true' and 'false' are truthy, so signInState is always truthy.
While you could perform string comparisons inside toggleSignIn to determine what to pass to the state setter, calling the state setter inline in the buttons would be easier.
<button onClick={() => { setSignInState(true); }}>Log In</button>
<button onClick={() => { setSignInState(false); }}>Sign Up</button>
Here the id from event object will always be Boolean true as they are not booleans they are strings, i.e., whatever you keep as value in a DOM attribute it would be a string in most of the cases and any string except empty string "" is true ...
The answer from CertainPerformance is better and easy to understand
In case you want to keep your code same and changing a little as below should work
function toggleSignIn(event) {
setSignInState(event.target.id === "true" ? true : false);
}
I am trying to submit data from a form on my page to a react.js api using axios but i get the following error.
import axios from 'axios';
import React, { Component } from 'react'
import { Link } from 'react-router-dom';
class AddStudent extends Component {
state = {
name:'',
course:'',
email:'',
phone:'',
}
handleInput = (e) => {
this.setState
({
[e.target.name]:e.target.value
});
}
saveStudent = async (e) =>{
e.preventDefault();
const res = await axios.post('http://127.0.0.1:8000//api/add-student',this.state);
if(res.data.status === 200)
{
console.log(res.data.message);
this.setState({
name:'',
course:'',
email:'',
phone:'',
});
}
}
render()
{
return (
<div className="container">
<div className="row">
<div className="col-md-6">
<div className="card">
<div className="card-holder">
<h4>
Add Student
<Link to={'/'} className="btn btn-primary btn-sm float-end"> Back </Link>
</h4>
</div>
<div className='card-body'>
<form onSubmit={this.saveStudent} >
<div className="form-group mb-3">
<label>Student Name</label>
<input type="text" name="name" onChange={this.handleInput} value={this.state.name} className="form-control" />
</div>
<div className="form-group mb-3">
<label>Student Course</label>
<input type="text" name="course" onChange={this.handleInput} value={this.state.course} className="form-control" />
</div>
<div className="form-group mb-3">
<label>Student Email</label>
<input type="text" name="email" onChange={this.handleInput} value={this.state.email} className="form-control" />
</div>
<div className="form-group mb-3">
<label>Student Phone</label>
<input type="text" name="phone" onChange={this.handleInput} value={this.state.phone} className="form-control" />
</div>
<div className="form-group mb-3">
<button type="submit" className="btn btn-primary">Save Student</button>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
);
}
}
export default AddStudent
this is my student controller data which I want to send in my dtabase but it giving error --> "AxiosError {message: 'Request failed with status code 404', name: 'AxiosError', code: 'ERR_BAD_REQUEST', config: {…}, request: XMLHttpRequest, …}
code: "ERR_BAD_REQUEST" "
<?php
namespace App\Http\Controllers\Api;
use App\Models\Student;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
class StudentController extends Controller
{
public function store(Request $request)
{
$student= new Student;
$student->name= $request-> input('name');
$student->course= $request-> input('course');
$student->email= $request-> input('email');
$student->phone= $request-> input('phone');
$student ->save();
return response()->json([
'status'=> 200,
'message'=>'Student added Successfully',
]);
}
}
here it is my .env file
APP_NAME=Laravel
APP_ENV=local
APP_KEY=base64:08iFPF3lcJqA98M9d9+lUeYi88nVtkHCWk2XIV6dKBU=
APP_DEBUG=true
APP_URL=http://localhost
LOG_CHANNEL=stack
LOG_DEPRECATIONS_CHANNEL=null
LOG_LEVEL=debug
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=laravelreactjs
DB_USERNAME=root
DB_PASSWORD=
BROADCAST_DRIVER=log
CACHE_DRIVER=file
FILESYSTEM_DISK=local
QUEUE_CONNECTION=sync
SESSION_DRIVER=file
SESSION_LIFETIME=120
MEMCACHED_HOST=127.0.0.1
REDIS_HOST=127.0.0.1
REDIS_PASSWORD=null
REDIS_PORT=6379
MAIL_MAILER=smtp
MAIL_HOST=mailhog
MAIL_PORT=1025
MAIL_USERNAME=null
MAIL_PASSWORD=null
MAIL_ENCRYPTION=null
MAIL_FROM_ADDRESS="hello#example.com"
MAIL_FROM_NAME="${APP_NAME}"
AWS_ACCESS_KEY_ID=
AWS_SECRET_ACCESS_KEY=
AWS_DEFAULT_REGION=us-east-1
AWS_BUCKET=
AWS_USE_PATH_STYLE_ENDPOINT=false
PUSHER_APP_ID=
PUSHER_APP_KEY=
PUSHER_APP_SECRET=
PUSHER_APP_CLUSTER=mt1
MIX_PUSHER_APP_KEY="${PUSHER_APP_KEY}"
MIX_PUSHER_APP_CLUSTER="${PUSHER_APP_CLUSTER}"
I hope the mistake is in the url "http://127.0.0.1:8000//api/add-student". You have provided // after port number "8000". It has to be /. The 404 error is "Page not found" error. In case, If you get this error. You need to check whether the url is properly configured axios react or check whether the url is found in api.php in laravel.
I was using something like this
axios.get(https://jsonplaceholder.typicode.com/posts/${id})
Initially I used ('https://jsonplaceholder.typicode.com/posts/${id}'). See the changes at (' with ). I am not sure at all if this could be valid here but you can give it a try and change ' with in your Api link and try if it works.
I'm trying to update the state of my component with useState in a register functional component。
when user input an invalid email address and click the submit button,
the following piece of code will return an error message
let response= await axios.post("/api/user/register",new_user,config);
I want to set error message into formData with this piece of code .
let response= await axios.post("/api/user/register",new_user,config);
if(response.data.errnum!==0){
setFormData({...formData,errors:response.data.message})
console.log(formData);
}
but the value of errors is empty,like this
What should I do to set error message into formData?
Here is my code:
import React ,{useState}from 'react'
import axios from "axios"
function Register() {
const [formData,setFormData]=useState({
name:"",
email:"",
password:"",
password2:"",
errors:{}
});
const {name,email,password,password2}=formData;
const setValue= e =>setFormData({...formData,[e.target.name]:e.target.value})
const submitData=async (e) =>{
e.preventDefault();
if(password!==password2){
console.log("passwords do not match ");
}else{
let new_user={name,email,password,}
try{
let config={
header:{
'Content-Type':'applicaiton/json'
}
}
let response= await axios.post("/api/user/register",new_user,config);
if(response.data.errnum!==0){
setFormData({...formData,errors:response.data.message})
console.log(formData);
}
}catch(error){
console.error(error);
}
}
}
return (
<div>
<section className="container">
<h1 className="large text-primary">Sign Up</h1>
<p className="lead"><i className="fas fa-user"></i> Create Your Account</p>
<form className="form" onSubmit={e=>submitData(e)}>
<div className="form-group">
<input
type="text"
placeholder="Name"
name="name"
value={name}
onChange={e=>setValue(e)}
required />
</div>
<div className="form-group">
<input
type="email"
placeholder="Email Address"
onChange={e=>setValue(e)}
value={email}
name="email" />
<small className="form-text">This site uses Gravatar so if you want a profile image, use aGravatar email</small>
</div>
<div className="form-group">
<input
type="password"
placeholder="Password"
onChange={e=>setValue(e)}
value={password}
name="password"
minLength="6"
/>
</div>
<div className="form-group">
<input
type="password"
placeholder="Confirm Password"
onChange={e=>setValue(e)}
value={password2}
name="password2"
minLength="6"
/>
</div>
<input type="submit" className="btn btn-primary" value="Register" />
</form>
<p className="my-1">
Already have an account? Sign In
</p>
</section>
</div>
)
}
export default Register
I think what you are doing wrong is that you are saving and object inside another object
const [formData,setFormData]=useState({
name:"",
email:"",
password:"",
password2:"",
errors:{}
});
formData is an object while errors is also an object.To go for a better approach make a seperate state for errors and append all the errors coming through those messages in an error object.
If you write a message in errors object where it is defined it will give you error
errors:{"hi","bye"}
There is no issue in your code. What you are trying to do is console the state as soon as you are setting it up.
setState is asynchronous which means you can’t call it on one line and assume the state has changed on the next.
If you check React docs
setState() does not immediately mutate this.state but creates a pending state transition. Accessing this.state after calling this method can potentially return the existing value. There is no guarantee of synchronous operation of calls to setState and calls may be batched for performance gains.
I'd suggest you use useEffect and then check for change in data of your state.
useEffect(() => {
console.log(formData)
}, [formData])
I have a simple form build from React. Upon submission, if the error comes back, I wish to render an extra div to show error on the form.
Right now I got it to work but I do not like the solution. My solution is based on the knowledge that the component will only re-render if the state changes inside the render function (In this case this.state.errorMessages). So I had to explicitly put the if condition inside the render function like so
renderError() {
var errArr = [];
for (var key in this.state.errorMessages) {
errArr = [...errArr, ...this.state.errorMessages[key]];
}
return (
<div className="alert alert-danger">
{errArr.map((err) => {
return <p>{err}</p>
})}
</div>
)
}
renderForm() {
return (
<form onSubmit={this.handleRegisterFormSubmit}>
<div className="form-group">
<label>First Name</label>
<input type="text" className="form-control" name="name" placeholder="Name" value={this.state.firstName} onChange={this.handleFirstNameChange} required/>
</div>
<div className="form-group">
<label>Last Name</label>
<input type="text" className="form-control" name="lastName" placeholder="Last Name" value={this.state.lastName} onChange={this.handleLastNameChange} required/>
</div>
<div className="form-group">
<label>Email address</label>
<input type="email" className="form-control" id="exampleInputEmail1" aria-describedby="emailHelp" placeholder="Enter email" value={this.state.email} onChange={this.handleEmailChange} />
<small id="emailHelp" className="form-text text-muted">We'll never share your email with anyone else.</small>
</div>
<div className="form-group">
<label>Password</label>
<input type="password" className="form-control" name="password" placeholder="Password" value={this.state.password} onChange={this.handlePasswordChange}/>
</div>
<div className="form-group">
<label>Password Confirmation</label>
<input type="password" className="form-control" name="password_confirmation" placeholder="Password Confirmation" value={this.state.passwordConfirmation} onChange={this.handlePasswordConfirmationChange}/>
</div>
<div>
<button type="submit" className="btn btn-primary">Submit</button>
<button type="button" className="btn btn-danger" onClick={this.handleCancelClick}>Cancel</button>
</div>
</form>
)
}
render () {
if (!this.state.errorMessages) {
return (
<div>
{this.renderForm()}
</div>
)
} else {
return (
<div>
{this.renderForm()}
{this.renderError()}
</div>
)
}
}
I don't really like this approach as this could get nasty if I have more condition to re-render. I'm hoping there is a solution along the line of not having much logic in the actual render function and have that extracted out. For example...
renderError() {
if (!this.state.errorMessages) {
return;
}
var errArr = [];
for (var key in this.state.errorMessages) {
errArr = [...errArr, ...this.state.errorMessages[key]];
}
return (
<div className="alert alert-danger">
{errArr.map((err) => {
return <p>{err}</p>
})}
</div>
)
}
render () {
<form onSubmit={this.handleRegisterFormSubmit}>
<div className="form-group">
<label>First Name</label>
<input type="text" className="form-control" name="name" placeholder="Name" value={this.state.firstName} onChange={this.handleFirstNameChange} required/>
</div>
<div className="form-group">
<label>Last Name</label>
<input type="text" className="form-control" name="lastName" placeholder="Last Name" value={this.state.lastName} onChange={this.handleLastNameChange} required/>
</div>
<div className="form-group">
<label>Email address</label>
<input type="email" className="form-control" id="exampleInputEmail1" aria-describedby="emailHelp" placeholder="Enter email" value={this.state.email} onChange={this.handleEmailChange} />
<small id="emailHelp" className="form-text text-muted">We'll never share your email with anyone else.</small>
</div>
<div className="form-group">
<label>Password</label>
<input type="password" className="form-control" name="password" placeholder="Password" value={this.state.password} onChange={this.handlePasswordChange}/>
</div>
<div className="form-group">
<label>Password Confirmation</label>
<input type="password" className="form-control" name="password_confirmation" placeholder="Password Confirmation" value={this.state.passwordConfirmation} onChange={this.handlePasswordConfirmationChange}/>
</div>
<div>
<button type="submit" className="btn btn-primary">Submit</button>
<button type="button" className="btn btn-danger" onClick={this.handleCancelClick}>Cancel</button>
</div>
{this.renderError}
</form>
}
This throws an error because it complains that this.renderError should be called as a function. But when I put it as
this.renderError()
The error will never render because it does not get automatically called when errors come back.
-----------Update----------
Alternatively, why can't I do something like the following
render () {
<div>
<form onSubmit={this.handleRegisterFormSubmit}>
...
</form>
{if (this.state.errorMessages) {this.renderError()}}
</div>
}
This throws console error
Uncaught Error: Module build failed: SyntaxError: Unexpected token
(117:13)
----------Update 2-----------
Essentially, I'm looking for a solution where inside the render function, I can easily show a whole block of code when the state changes. In Vue, I can do something like
<form>
<input type="text">
</form>
<div v-if="hasError">
<div class="alert alert-danger">{{something}}</div>
</div>
Can I do something as easy as this in React?
You can just use map in order to extract the error message from your object.
Here below a minimal example of form validations and errors in React. It's good to understand how it works, but for my part, I use Formik which simplifies this process.
class Test extends React.Component {
constructor(props) {
super(props);
this.state = { errorMessages: {} };
}
handleRegisterFormSubmit = e => {
e.preventDefault(); // don't submit the form until we run what's below
let errorMessages = {};
if (!this.state.lastName) errorMessages.lastName = 'You need to enter your last name';
// And so on for each field validation
// Do we have errors ?
if (Object.keys(errorMessages).length > 0) {
this.setState(errorMessages);
} else {
// Submit to server
}
};
handleChange = e => {
this.setState({
[e.target.name]: e.target.value,
errorMessages: {
...this.state.errorMessages,
[e.target.name]: null // remove the error of this field if it's being edited
}
});
};
render() {
const errArr = Object.keys(this.state.errorMessages).map(key => this.state.errorMessages[key]);
return (
<form onSubmit={this.handleRegisterFormSubmit}>
<div className="form-group">
<label>Last Name</label>
<input type="text" className="form-control" name="lastName" placeholder="Last Name" value={this.state.lastName} onChange={this.handleChange} />
</div>
{/* ... your dom */}
<div>
<button type="submit" className="btn btn-primary">
Submit
</button>
<button type="button" className="btn btn-danger" onClick={this.handleCancelClick}>
Cancel
</button>
</div>
{errArr.length > 0 && (
<div className="alert alert-danger">
{errArr.map(err => {
return <p>{err}</p>;
})}
</div>
)}
</form>
);
}
}
One more way to not display your alert div is with a ternary operator for your className and using bootstrap's d-none
<div className={errArr.length ? "alert alert-danger" : "d-none"}>
{errArr.map(err => {
return <p>{err}</p>;
})}
</div>
I believe this is an architectural question.
Try to follow those practices:
1- Inject conditional statement inside JSX directly
2- Use functional components to render JSX not object methods
1- Inject conditional statement inside JSX directly
Bad:
if (!this.state.errorMessages) {
return (
<div>
{this.renderForm()}
</div>
)
} else {
return (
<div>
{this.renderForm()}
{this.renderError()}
</div>
)
}
Good:
return <div>
{this.renderForm()}
{this.state.errorMessages && this.renderError()}
</div>
2- Use functional components to render JSX not object methods
Bad:
class FormComponent {
// ....
renderError() {
// Blah blah blah
return (
<div className="alert alert-danger">
{errArr.map((err) => {
return <p>{err}</p>
})}
</div>
)
}
render() {
return (
<div>
<AnotherComponent />
{this.renderError()}
<div/>
)
}
}
then {this.renderError()}
Good
class FormComponent {
// ....
render() {
return (
<div>
<AnotherComponent />
{<Error />} {/* render it as componet ⚠️*/}
<div/>
)
}
}
// Build it as component outside the main component (FormComponent) ⚠️
function Error(props) {
return (
<div className="alert alert-danger">
{props.errArr.map((err) => {
return <p>{err}</p>
})}
</div>
)
}
I spent many 2 years in React development of enterprise apps also graduating from Udacity and I am sharing my experience here. Congrats!
One would usually render items in an element representing the list with some styling applied. We also sometimes don't want this wrapping element if we don't have any items.
I've written the following component which allows conditional rendering. When the condition is false, no elements are rendered keeping the DOM clean.
export default class If extends Component<{ condition: any }, {}> {
render() {
return this.props.condition ? this.props.children : <Fragment></Fragment>;
}
}
One can now simply use the component as follow:
<If condition={items.length}>
<-- item list -->
</If>
I am new in reactjs. I am creating a sample project using reactjs. First I am getting error like state is null. After setting intial state i am getting error
I got Warning: valueLink prop on input is deprecated; set value and onChange instead
I know there are many question related to this but my problem is not solved please help.
Here is code:
import React, {Component} from 'react';
import {Link} from 'react-router'
import validator from 'validator';
import LinkedStateMixin from 'react-addons-linked-state-mixin';
module.exports = React.createClass({
mixins: [LinkedStateMixin],
getInitialState() {
return {};
},
saveData: function(){
//console.log(this.state)
},
render () {
return (
<form>
<div className="page-content container">
<div className="row">
<div className="col-md-4 col-md-offset-4">
<div className="login-wrapper">
<div className="box">
<div className="content-wrap">
<h6>Sign Up</h6>
<input className="form-control" name ="email" placeholder="E-mail address" type="text" valueLink={this.linkState('email')}/>
<input className="form-control" name="password" placeholder="Password" type="password"/>
<input className="form-control" placeholder="Confirm Password" type="password" />
<div className="action">
<button type="button" className ="btn btn-primary signup" onClick={this.saveData}>Sign Up</button>
</div>
</div>
</div>
<div className="already">
<p>Have an account already?</p>
<Link to ="/reactApp/">Login</Link>
</div>
</div>
</div>
</div>
</div>
</form>
)
}
});
Please read more about the fundamentals of React and handling state in forms in the React documentation. No mixins or anything complicated required. Also as stated above "ReactLink is deprecated as of React v15. The recommendation is to explicitly set the value and change handler, instead of using ReactLink."
Each of your text inputs should have a change handler just like the error message says... There are many ways you could accomplish this but below is a basic example. Check out the snippet below in a fiddle here https://jsfiddle.net/09623oae/
React.createClass({
getInitialState: function() {
return({
email: "",
password: "",
passwordConfirmation: ""
})
},
submitForm: function(e) {
e.preventDefault()
console.log(this.state)
},
validateEmail: function(e) {
this.setState({email: e.target.value})
},
validatePassword: function(e) {
this.setState({password: e.target.value})
},
confirmPassword: function(e) {
this.setState({passwordConfirmation: e.target.value})
},
render: function() {
return (
<form onSubmit={this.submitForm}>
<input
type="text"
value={this.state.email}
onChange={this.validateEmail}
placeholder="email"
/>
<input
type="password"
value={this.state.password}
onChange={this.validatePassword}
placeholder="password"
/>
<input
type="password"
value={this.state.passwordConfirmation}
onChange={this.confirmPassword}
placeholder="confirm"
/>
</form>
)
}
});
Solution
You cannot use valueLink anymore, instead use onChange react event to listen for input change, and value to set the changed value.
class MyForm extends React.Component {
constructor(props) {
super(props);
this.state = {value: 'Hello!'};
this.handleChange = this.handleChange.bind(this);
}
handleChange(event) {
this.setState({value: event.target.value});
}
render() {
return (
<input
type="text"
value={this.state.value}
onChange={this.handleChange}
/>
);
}
Clarification
Notice that since the value is set from a state, it will only get updated from changing the attached state, writing in the input does nothing, unless you listen for the input changed (via onChange event) and update the state accordingly.
source: from React documentation
You should set your state to atleast empty initially, if you want to access it at a later point of time. Something similar to below will do
getInitialState() {
return {};
},
ReactLink Without valueLink
You can change with
<input type="text" value={valueLink.value} onChange={handleChange} />
Reference:
https://facebook.github.io/react/docs/two-way-binding-helpers.html
This warning happens because the React Link was deprecated in React 0.15:
ReactLink is deprecated as of React v15. The recommendation is to
explicitly set the value and change handler, instead of using
ReactLink.
So, instead of use this.linkState('email') and valueLink:
<input className="form-control"
name ="email"
placeholder="E-mail address"
type="text"
valueLink={this.linkState('email')}/>
Use this.state.email and an onChange function:
callThisWhenChangeEmail: function(emailFromInput) {
this.setState({
email: emailFromInput
});
},
render () {
/* the existent code above */
<input className="form-control"
name ="email"
placeholder="E-mail address"
type="text"
value={this.state.email}
onChange={this.callThisWhenChangeEmail}/>
/* the existent code below */
}
When the user type some e-mail in the input, the function callThisWhenChangeEmail is called, receiving the e-mail as parameter (emailFromInput). So, you only need to set this e-mail in the state.