Hello everybody I'm wondering if I can pass a state value from a component to other where I'm returning jsx code to be displayed for example I have 3 components.
1
import React, { Component } from 'react';
import Conteneur from './Conteneur';
class Header extends React.Component {
constructor(props) {
super(props);
this.state = { value: '' };
this.handleChange = this.handleChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}
handleChange(event) {
this.setState({ value: event.target.value });
}
handleSubmit(event) {
alert('A name was submitted: ' + this.state.value);
event.preventDefault();
}
render() {
return (
<form onSubmit={this.handleSubmit}>
<label>
Name:
<input type="text" value={this.state.value} onChange={this.handleChange} />
</label>
<input type="submit" value="Submit" />
<Conteneur values={this.state.value} />
</form>
);
}
}
export default Header;
2 app.js
import React, { Component } from 'react';
import Header from './Header';
import Conteneur from './Conteneur';
import './App.css';
class App extends Component {
render() {
return (
<div className="App" >
<br />
<Header />
<br />
<Conteneur />
</div>
);
}
}
export default App;
3 and finally
import React, { Component } from 'react';
const Conteneur = () => {
return (
<div className="tab"><span>ok test </span></div>
);
};
export default Conteneur;
I like to pass the state value of header that I have from the input to conteneur and then display in the box while I have some code all the examples that I saw online they are sending state like this:
class Dashboard extends Component {
...
...
render(){
return(
<Sidebar data={this.state.data1}/>
);
}
}
So can I do like this <Conteneur values={this.state.value} /> in the form ?
And I imported Conteneur.
i updated the code but the output is
Yes you can do, only one thing you are missing. Receive the props in the function parameters then render that in the ui.
Like this:
const Conteneur = (props) => {
return (
<div className="tab"><span>value: {props.value} </span></div>
);
};
Related
I am building a To-Do List web app with React as my first project.
I want to implement local storage which works fine only that,I am unable to handle check and uncheck of the checkbox prefectly.
Here is a link to the deployed website so you can understand the problem I am having.
https://rapture-todo.netlify.app/
When you add a todo, and mark it complete.
on reload, the checkbox of the todo is unchecked but the todo is marked complete.
Here is my source code[github link- https://github.com/coolpythoncodes/React-ToDo-List].
For App.js
import React, { Component } from 'react';
import Header from './component/Header';
import Info from './component/Info';
import AddToDo from './component/AddToDo';
import TodoListItem from './component/TodoListItem';
import './sass/main.scss';
class App extends Component{
constructor(props){
super(props);
this.state= {
value: '',
list: [],
show: true,
};
this.handleChange= this.handleChange.bind(this);
this.handleSubmit= this.handleSubmit.bind(this);
this.handleInputChange = this.handleInputChange.bind(this);
this.deleteTask = this.deleteTask.bind(this);
}
componentDidMount() {
const list = window.localStorage.getItem('userTodo') ? JSON.parse(localStorage.getItem('userTodo')) : [];
this.setState({ list })
}
handleChange(e) {
this.setState({value:e.target.value})
}
// Handle submission of user todo item
handleSubmit(e) {
e.preventDefault();
const newTask = {
id: Date.now(),
userTodo: this.state.value,
isCompleted: false,
checked: false,
}
// Validate form so user doesn't add an empty to do
if (this.state.value.length > 0) {
this.setState({
list: [newTask, ...this.state.list],
value: '', // Clear input field
show: true, // Success message
}, ()=>{
window.localStorage.setItem('userTodo', JSON.stringify(this.state.list));
})
}
}
// Handles checkbox
handleInputChange(id) {
this.setState({list: this.state.list.map(item => {
if (item.id === id) {
item.isCompleted = !item.isCompleted;
item.checked = !this.state.checked;
}return item
})}, ()=>{
window.localStorage.setItem('userTodo', JSON.stringify(this.state.list));
})
}
// Delete a task
deleteTask(id){
this.setState({list: this.state.list.filter(item => item.id !== id )},()=>{
window.localStorage.setItem('userTodo', JSON.stringify(this.state.list))
})
console.log(this.state.list)
}
render(){
return(
<div>
<Header />
<Info />
<AddToDo onChange={this.handleChange} value={this.state.value} onSubmit={this.handleSubmit} />
<TodoListItem deleteTask={this.deleteTask} onChange={this.handleInputChange} list={this.state.list} defaultChecked={this.state.checked} />
</div>
)
}
}
export default App;
For TodoListItem.js
import React, { Component } from 'react';
import ToDoItem from './ToDoItem';
import '../sass/main.scss';
class ToDoListItem extends Component{
render(){
const {list, onChange, deleteTask, defaultChecked} = this.props;
return(
<div>
{list.map((todo)=>{
return (
<ToDoItem
key={todo.id}
userTodo={todo.userTodo}
isCompleted={todo.isCompleted}
onChange={onChange}
id={todo.id}
deleteTask={deleteTask}
defaultChecked={defaultChecked}
/>
)
})}
</div>
)
}
}
export default ToDoListItem;
For TodoItem.js
import React, { Component } from 'react';
import { FontAwesomeIcon } from '#fortawesome/react-fontawesome'
import { faTrashAlt } from '#fortawesome/free-solid-svg-icons'
import '../sass/main.scss';
class ToDoItem extends Component{
render(){
const {userTodo, isCompleted, onChange, id, deleteTask, defaultChecked} = this.props;
const checkStyle = isCompleted ? 'completed-todo' : 'not-completed-todo';
return(
<div className={`container ${checkStyle}`}>
<input type="checkbox" onChange={onChange.bind(this, id)} defaultChecked={defaultChecked}/>
<div >
<p className='title'>{userTodo}</p>
</div>
{/* Delete button */}
<button onClick={deleteTask.bind(this, id)}><FontAwesomeIcon className='remove-icon' icon={faTrashAlt} /></button>
</div>
)
}
}
export default ToDoItem;
Please note: I have gone through other questions similar to the problem I am having but I could not solve this problem.
If I did not state the question well, please let me know.
In the below code in App.js,
<TodoListItem deleteTask={this.deleteTask} onChange={this.handleInputChange} list={this.state.list} defaultChecked={this.state.checked} />
You are setting, defaultChecked={this.state.checked} Why do you do that? There is nothing called checked in the state.
In fact, there is no need to pass the defaultValue.
Make the following changes,
In App.js, remove defaultValue prop for TodoListItem
<TodoListItem deleteTask={this.deleteTask} onChange={this.handleInputChange} list={this.state.list}/>
In TodoListItem.js, remove defaultChecked={defaultChecked}
<ToDoItem
key={todo.id}
userTodo={todo.userTodo}
isCompleted={todo.isCompleted}
onChange={onChange}
id={todo.id}
deleteTask={deleteTask}
defaultChecked={defaultChecked} // Remove this.
/>
In ToDoItem.js,
<input type="checkbox"onChange={onChange.bind(this, id)}
defaultChecked={isCompleted} // Replace defaultValue with isCompleted
/>
I am a beginner in react js so what I want to do it is :
I want to pass the quizData array to another component , data in quizData is set from a callback function which is submitForm function . But when I try to print the prop in another Component(QuizScreen)
it prints 1 as the value console .
Can anybody Please suggest . Am I doing something wrong with the design pattern ?
Thanks in Advance.
import React from 'react';
import logo from './logo.svg';
import './App.css';
import QuizForm from './QuizForm.js'
import QuizScreen from './QuizScreen';
class App extends React.Component{
state = {
isSubmitted : false,
quizData : [],
}
submitForm = (data) =>{
this.setState({isSubmitted : true,
quizData : this.state.quizData.push(data)
})
console.log("Value of quizData is "+ JSON.stringify(this.state.quizData))
}
render() {
return (
<div className="App">
<div className= "container">
{(!this.state.isSubmitted) ? <QuizForm isFormSubmit= {this.submitForm} /> : <QuizScreen details={this.state.quizData}/>}
</div>
</div>
);
}
}
export default App;
import React from 'react'
class QuizScreen extends React.Component {`enter code here`
constructor(props)
{
super(props)
console.log("Props is "+JSON.stringify(props.details))
}
render(){
return(
<div className= "App">
</div>
)
}
}
export default QuizScreen;
import React , {Component} from 'react'
import FileUpload from './FileUpload';
import QuizScreen from './QuizScreen.js'
import './QuizForm.css'
import InputTextField from './InputTextField';
import fields from './Fields.js';
class QuizForm extends Component {
constructor(props) {
super(props);
this.state = {
value: '',
fileData : [],
negativeMarking : 0,
quizName : '',
category :'',
weightage : 0,
quizTime: '',
isSubmitted: false
};
this.handleChange = this.handleChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}
myfile = (fileUploadData) =>{
console.log("Hello from myfile"+JSON.stringify(fileUploadData));
this.setState({fileData : fileUploadData})
}
handleChange(event) {
console.log("My values are "+event.target.name)
const value = event.target.value;
this.setState({[event.target.name] :value })
}
handleSubmit(event) {
alert('QuizName is '+event.target.quizName.value)
event.preventDefault();
this.setState({isSubmitted : true})
this.props.isFormSubmit(this.state)
}
render() {
return (
<div className="form-style-6">
<h1>Create Quiz</h1>
<form onSubmit={this.handleSubmit}>
{fields.map(form =>{
return(
<InputTextField
type={form.type}
name={form.name}
_handleChange={this.handleChange}
placeholder= {form.placeholder}
key={form.placeholder}
/>
);
} )}
<FileUpload onFileUpload = {this.myfile}/>
<input type="submit" value="Submit"/>
</form>
</div>
);
}
}
export default QuizForm;
You have to refer the current component scope by putting this keyword when you want to access props. Plus, print it on your console by calling it inside a componentDidMount().
import React from 'react';
class QuizScreen extends React.Component {
constructor(props) {
super(props);
}
componentDidMount() {
console.log('Props is ' + JSON.stringify(this.props.details)); //<-- Here you have to put `this` keyword.
}
render() {
return <div className="App"></div>;
}
}
export default QuizScreen;
import React , {Component} from 'react'
import FileUpload from './FileUpload';
import QuizScreen from './QuizScreen.js'
import './QuizForm.css'
import InputTextField from './InputTextField';
import fields from './Fields.js';
class QuizForm extends Component {
constructor(props) {
super(props);
this.state = {
value: '',
fileData : [],
negativeMarking : 0,
quizName : '',
category :'',
weightage : 0,
quizTime: '',
isSubmitted: false
};
this.handleChange = this.handleChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}
myfile = (fileUploadData) =>{
console.log("Hello from myfile"+JSON.stringify(fileUploadData));
this.setState({fileData : fileUploadData})
}
handleChange(event) {
console.log("My values are "+event.target.name)
const value = event.target.value;
this.setState({[event.target.name] :value })
}
handleSubmit(event) {
alert('QuizName is '+event.target.quizName.value)
event.preventDefault();
this.setState({isSubmitted : true})
this.props.isFormSubmit(this.state)
}
render() {
return (
<div className="form-style-6">
<h1>Create Quiz</h1>
<form onSubmit={this.handleSubmit}>
{fields.map(form =>{
return(
<InputTextField
type={form.type}
name={form.name}
_handleChange={this.handleChange}
placeholder= {form.placeholder}
key={form.placeholder}
/>
);
} )}
<FileUpload onFileUpload = {this.myfile}/>
<input type="submit" value="Submit"/>
</form>
</div>
);
}
}
export default QuizForm;
I'm new to React and i'm trying to pass data (a date - 'dd/mm/yyyy') to a second page from an input box on the home page. I'm confused as to where i put my Link, what information i put in the redirect(if any) and also the syntax to send and receive it on page it. Here is the code i have so far. Please can anybody help?:
class Home extends React.Component {
constructor(props) {
super(props);
this.state = { inputDate: '' };
}
myChangeHandler = (event) => {
this.setState({inputDate: event.target.value});
}
render() {
let dateEntered = this.state.inputDate
return (
<form>
<h3 >Enter Date :
<input
type="text" className="input-text" placeholder={"DD/MM/YYYY"} onChange={this.myChangeHandler}
/>
</h3>
<button className="button half-page-width-button button-blue1"><Link to={{
pathname: '/Page1',
state: [{dateEntered}]
}}>Submit Date</Link>
</button>
</form>
);
}
}
Thanks again
Thank you for getting back to me. My receiving component looks like this. Where would I put the code? In the render section?
import React, {Component} from 'react';
import Home from './components/Home';
import './App.css';
class Page1 extends Component {
render() { // Table Data
return (
<form>
<h3 >Enter Date :
<input
type="text" className="input-text" value={this.state.header}
/>
</h3>
</form>
);
}
}
export default Page1;
You can make use of state to pass on to data to the Link Component and receive it from location in the component rendered at /Page1 path
class Home extends React.Component {
constructor(props) {
super(props);
this.state = { inputDate: '' };
}
myChangeHandler = (event) => {
this.setState({inputDate: event.target.value});
}
render() {
let dateEntered = this.state.inputDate
return (
<form>
<h3 >Enter Date :
<input
type="text" className="input-text" placeholder={"DD/MM/YYYY"} onChange={this.myChangeHandler}
/>
</h3>
<button className="button half-page-width-button button-blue1"><Link to={{
pathname: '/Page1',
state: {dateEntered}
}}>Submit Date</Link>
</button>
</form>
);
}
}
In the receiving component
class Page1 extends Component {
render() { // Table Data
const { dateEntered } = this.props.location.state || {};
return (
<form>
<h3 >Enter Date :
<input
type="text" className="input-text" value={this.state.header}
/>
</h3>
</form>
);
}
}
export default Page1;
I intend to create a to-do list without using ref as in the many examples, but it isn't working.
The expected behavior is that upon entering an entry, it will show up at the top and upon clicking add, it will create an input box for entering an entry. Currently, upon entering the state returns undefined.
The code can be found below or in this sandbox:
import React, { Component } from 'react';
import { render } from 'react-dom';
import './style.css';
import ToDo from './todo'
class App extends Component {
constructor() {
super();
this.state = {
todos: []
};
}
onChange=(e)=>{
const newToDos = [...this.state.todos]
newToDos.push(e.target.value)
this.setState({
todos: newToDos
})
}
onAdd=(e)=>{
e.preventDefault();
const newtodos=[...this.state.todos]
this.setState({
todos: newtodos.push("")
})
}
render() {
console.log(this.state.todos)
return (
<div>
<p>All the to-dos include {this.state.todos}</p>
<ToDo
todos={this.state.todos}
/>
<form onSubmit={this.onChange}>
<input
type="text"
placeholder="add a new todo..."
/>
</form>
<button onClick={this.onAdd}>+</button>
</div>
);
}
}
render(<App />, document.getElementById('root'));
And here is the todo.js:
import React, { Component } from 'react';
import { render } from 'react-dom';
export default class ToDo extends Component {
constructor(props){
super(props)
}
render() {
const {todos, onChange}=this.props
return (
<div>
{
todos.map((todo, index)=>
<div>
{todo}
</div>
)
}
</div>
);
}
}
You can store your new todo in state when onChange input and add this into todos when click save.
I have forked and edit your sample.
https://stackblitz.com/edit/react-nwtp5g?file=index.js
BTW: In your sample, newtodos.push("") will return the length of newtodos array, not the array after pushed.
onAdd=(e)=>{
e.preventDefault();
const newtodos=[...this.state.todos]
this.setState({
todos: newtodos.push("")
})
Hope this help.
your code newtodos.push("") dosent return array so no map function:
this.setState({
todos: newtodos.push("")
})
correct it something like this
this.setState({
todos: newtodos.concat("new value")
})
You have a problem with this code,
<form onSubmit={this.onChange}>
<input
type="text"
placeholder="add a new todo..."
/>
</form>
Here you are adding onSubmit on form, which will never call because you don't have submit button.
you should do something like this,
<form>
<input
type="text"
placeholder="add a new todo..."
onChange={this.onChange}
value={this.state.currentValue}
/>
</form>
onChange=(e)=>{
event.preventDefault();
this.setState({
currentValue: e.target.value
})
}
onAdd=(e)=>{
e.preventDefault();
const newToDos = [...this.state.todos]
newToDos.push(this.state.currentValue)
this.setState({
todos: newToDos,
currentValue: ''
})
}
Demo
Update
In your todo component you have useless constructor, If you don't have state in a component or don't have any function to bind this don't add constructor.
You can remove the constructor.
Another thing is, you are not passing any onChange prop to todo component, so here you will get undefined for onChange.
const {todos, onChange}=this.props
You can also write this component as a functional component.
You can update your code with
import React, { Component } from 'react';
import { render } from 'react-dom';
import './style.css';
import ToDo from './todo'
class App extends Component {
constructor() {
super();
this.state = {
todos: [],
inputText: ""
};
}
onAdd= () => {
this.setState({
todos: [...this.state.todos, this.state.inputText], textInput: ""
})
}
render() {
console.log(this.state.todos)
return (
<div>
<p>All the to-dos include {this.state.todos}</p>
<ToDo
todos={this.state.todos}
/>
<form>
<input
type="text"
placeholder="add a new todo..."
onChange={inputText => this.setState({inputText})}
/>
</form>
<button onClick={this.onAdd}>+</button>
</div>
);
}
}
render(<App />, document.getElementById('root'));
And in todo.js you can simply do
import React, { Component } from 'react';
import { render } from 'react-dom';
export default const ToDo = ({todos}) => {
return(<div>
{todos.map((todo, index) => (
<div key={index}>
{todo}
</div>))}
</div>)}
as it do not contains any state associated with it.
I am trying to pass data from one component to another. but it has no parent child relation and it is independent from each other. I want to do it using flux not redux. Can anyone help me to do this? below are my code.
export class EmpSearch extends React.Component {
constructor(props) {
super(props);
this.state = {
Empnumber: ''
};
}
updateEmpNumber(e) {
this.setState({Empnumber: e.target.value});
}
render() {
return (
<div className="row">
<form>
<div className="form-group">
<label htmlFor="Empnumber">Emp Number</label>
<input type="text" className="form-control" id="Empnumber" placeholder="Emp Number" value={this.state.Empnumber} onChange={this.updateEmpNumber.bind(this)}/>
</div>
</form>
</div>
);
}
}
export default EmpSearch
The other file is where i want to send the EmpNumber is below,
class EmpDetail extends React.Component {
render() {
return (
<div className="container">
<input type="text"/>
</div>
);
}
}
export default EmpDetail;
Assuming you have already implemented the flux architecture in your app.
your 1st component will be like this.
import React from 'react';
import UserAction from '../../Actions/UserActions';
export class EmpSearch extends React.Component {
constructor(props) {
super(props);
this.state = {
Empnumber: ''
};
}
updateEmpNumber(e) {
this.setState({Empnumber: e.target.value});
UserAction.employeeNumb(this.state.Empnumber);
}
render() {
return (
<div className="row">
<form>
<div className="form-group">
<label htmlFor="Empnumber">Emp Number</label>
<input type="text" className="form-control" id="Empnumber" placeholder="Emp Number" value={this.state.Empnumber} onChange={this.updateEmpNumber.bind(this)}/>
</div>
</form>
</div>
);
}
}
export default EmpSearch
The Actions file will look like
import {dispatch,register} from '../Dispatcher/Dispatcher';
export default {
employeeNumb(Data){
dispatch({ actionType:'EMPNO',data:Data});
}
}
The Store will look like
import {dispatch,register} from '../Dispatcher/Dispatcher';
import AppConstants from '../Constants/AppConstants';
import {EventEmitter} from 'events';
const CHANGE_EVENT = 'change';
var a=0;
const UserStore = Object.assign(EventEmitter.prototype,{
emitChange(){
this.emit(CHANGE_EVENT)
},
addChangeListener(callback){
this.on(CHANGE_EVENT,callback);
},
removeChangeListener(callback){
this.removeListener(CHANGE_EVENT,callback)
},
setEmpData(data){
a=data;
},
getEmpData(){
return a;
}
});
dispatcherIndex:register((action)=>{
switch (action.actionType) {
case AppConstants.EMPNO:
UserStore.setEmpData(action.data);
UserStore.emitChange();
break;
}
UserStore.emitChange();
});
export default UserStore;
The dispatcher file
import {Dispatcher} from 'flux';
const flux = new Dispatcher();
export function register(callback){
return flux.register(callback);
}
export function dispatch(actionType,action){
flux.dispatch(actionType,action);
}
and the 2nd Component file looks like
import React from 'react';
import Store from '../../Store/UserStore';
class EmpDetail extends React.Component {
constructor(props){
super(props);
this.state={
empno:''
};
}
componentDidMount(){
Store.addChangeListener(this._onChange);
}
componentWillUnmount = () =>{
Store.removeChangeListener(this._onChange);
}
_onChange = () =>{
this.setState({empno:Store.getEmpData()});
}
render() {
return (
<div className="container">
<input type="text"/>
<input type="button" onClick={()=>{console.log(this.state.empno);}}/>
</div>
);
}
}
export default EmpDetail;
What you have tried might be slightly different but this is the normal flow for what you are looking for.