I have a class with form and I want to pass entered data to next jsx file =>
Here is class ("sender")
import React from 'react'
import Button from './Button';
class Sender extends React.Component {
constructor() {
super();
this.state = {
imie: '',
};
this.redirect = this.redirect.bind(this);
this.handleChange = this.handleChange.bind(this);
}
handleChange({ target }) {
this.setState({
[target.name]: target.value
});
}
getData(){
const sendData = [
{
name: this.state.name
}
]
}
render() {
return (
<div className="order-wrapper">
<div className="order">
<div className="order-box">
<label htmlFor="name">Imie: </label>
<input
type="text"
name="name"
id="name"
value={ this.state.name }
onChange={ this.handleChange }
/>
</div>
<div className="order-box">
<Button
type="submit"
value="Zamów"
className="zamowbtn"
onClick={this.redirect}
/>
</div>
</div>
</div>
</div>
)
}
}
export default Sender
From this class I want to send name value which is located in getData() function.
I need that value in .jsx file below and show it in console.log(). How to do it? Please help me:)
import React from 'react'
import Sender from './Sender'
const Finish = () => {
return (
<div>
{ /* Here i need my 'name' value from Sender Class */ }
</div>
)
}
export default Finish
If there are in different parts of Application and one is not a parent of second one. You should use Context API for this
Related
I'm in the React work by 2 hours and I have a problem with how the writer separate correctly the component, an example I have these windows
When I click the button "Set" I change the value this.state.nameFramework, If I write all code inside the App component my helloApp work but if I write the code in the separate component it not work in the instant time but for change the value of the variable this.state.nameframework I had reloaded the page.
My code
require('normalize.css/normalize.css');
require('styles/App.css');
import React from 'react';
import InputFramework from 'components/InputFramework';
import ListPerson from 'components/ListPerson';
const list = [
{
objectID: 1,
'name': 'Vincenzo',
'surname': 'Palazzo'
},
{
objectID: 2,
'name': 'Sara',
'surname': 'Durante'
}
];
let name = 'Vincent';
let nameFramework = 'React';
class AppComponent extends React.Component {
constructor(props){
super(props);
this.state = {
list,
name,
nameFramework
};
this.onSelectPerson = this.onSelectPerson.bind(this);
this.onSubmitText = this.onSubmitText.bind(this);
this.onChangeNameFramework = this.onChangeNameFramework.bind(this);
}
onSubmitText(){
this.setState({nameFramework: this.state.nameFramework});
}
onChangeNameFramework(name){
this.state.nameFramework = name;
}
onSelectPerson(name) {
this.setState({name: name});
}
render() {
//This is no good for my programmer style, resolve it please
return (
<div className="index">
<InputFramework
name={this.state.name}
nameFramework={this.state.nameFramework}
onChange={this.onChangeNameFramework}
onClick={this.onSubmitText}
/>
<ListPerson
onClick={this.onSelectPerson}
list={this.state.list}/>
</div>
);
}
}
AppComponent.defaultProps = {
};
export default AppComponent;
Input component
require('normalize.css/normalize.css');
require('styles/App.css');
import React from 'react';
class InputFramework extends React.Component {
constructor(props){
super(props);
}
render() {
//This is no good for my programmer style, resolve it please
//The nameFramework not update
let {onChange, onClick, name} = this.props;
return (
<div className='index'>
<h1>Hello my name is {name} and I'm learning {this.props.nameFramework}</h1>
<from>
<input type='text'
onChange={event => onChange(event.target.value)}/>
<button type='submit' onClick={() => onClick}>Set</button>
</from>
</div>
);
}
}
InputFramework.defaultProps = {};
export default InputFramework;
List component
require('normalize.css/normalize.css');
require('styles/App.css');
import React from 'react';
class ListPerson extends React.Component {
constructor(props){
super(props);
}
render() {
//This is no good for my programmer style, resolve it please
const {onClick, list} = this.props;
return (
<div className="index">
<ul>
{list.map(function(item){
return (
<li key={item.objectID}>
{item.name}
<button type='button' onClick={() => onClick(item.name)}>Select</button>
</li>
)
})}
</ul>
</div>
);
}
}
ListPerson.defaultProps = {
};
export default ListPerson;
I this is a problem to how to write the code, now I ask you that you have more experience than me, can you help me to undestend.
You are trying to change (mutate) state directly in onChangeNameFramework handler.
Mutating state directly can lead to bugs.
State must be changed only by this.setState, so it must be like this:
onChangeNameFramework(name){
this.setState({
nameFramework: name
})
}
Here is the docs:
https://reactjs.org/docs/state-and-lifecycle.html#do-not-modify-state-directly
Another problem is in InputFramework component, when you submit a form the page reloads, to prevent it, you should add e.preventDefault() like this:
class InputFramework extends React.Component {
render() {
//This is no good for my programmer style, resolve it please
//The nameFramework not update
let {onChange, onClick, name} = this.props;
const handleClick = (e) => {
e.preventDefault();
onClick();
}
return (
<div className='index'>
<h1>Hello my name is {name} and I'm learning {this.props.nameFramework}</h1>
<form>
<input type='text'
onChange={event => onChange(event.target.value)}/>
<button type='submit' onClick={handleClick}>Set</button>
</form>
</div>
);
}
}
Lastly in AppComponent the following code is redundant, since you are setting the same state:
onSubmitText(){
this.setState({nameFramework: this.state.nameFramework});
}
You already handle the change of framework name in onChangeNameFramework handler.
I think using both onSubmitText and onChangeNameFramework handler seems unnecesary here, only one of them will be enough.
Playground:
https://codesandbox.io/s/blue-frost-qutb0
I'm learning React and I need help understanding how to create functions for values that are updated asynchronously in the DOM. For instance, I have a text input within a component called header that looks like this:
export default class Header extends React.Component {
constructor(props){
super(props);
}
render(){
return (
<div className="Header">
<div><input onKeyDown={this.props.onEnter} id="filter-results" className="full" type="text" placeholder="search kks"></input></div>
<div><button className="full">SEARCH</button></div>
</div>
);
}
}
, which is used to filter search results. The onEnter function tries to use the value updated in the input:
class App extends React.Component {
constructor(props){
super(props);
this.state = {
categories: [],
searchResults: [],
};
this.filterSearch = this.filterSearch.bind(this);
}
filterSearch(){
var el = document.getElementById('filter-results').value
console.log(el)
var result = this.state.categories.filter(row => {
var rx = new RegExp(el)
return rx.test(row['id'])
});
console.log(result)
}
render(){
return (
<div className="App">
<Header onEnter={this.filterSearch}/>
</div>
);
}
}
When I type something into the input, the element's value is logged to the console. The problem is, what is logged is always one character less than what I expect to see. If I type 'a', I get '', 'ab' => 'a', etc. I can understand conceptually that when the function is triggered and the logging occurs the value hasn't yet been updated, but I don't know how to wait for the value to be updated and then work with it. Can anyone help me?
Use onChange instead.
//change handler
handler(e) {
console.log(e.target.value)
}
//input's onChange event
onChange={ this.handler.bind(this) }
1) You should not be using native javascript to get value by id. This is not react way of doing.
App.js
import React from "react";
import ReactDOM from "react-dom";
import Header from "./Header";
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
categories: [],
searchResults: []
};
this.filterSearch = this.filterSearch.bind(this);
}
filterSearch(value) {
console.log(value);
var result = this.state.categories.filter(row => {
var rx = new RegExp(value);
return rx.test(row["id"]);
});
console.log(result);
}
render() {
return (
<div className="App">
<Header onEnter={this.filterSearch} />
</div>
);
}
}
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
// Header.js
import React from "react";
export default class Header extends React.Component {
constructor(props) {
super(props);
}
handleChange = ({ target }) => {
this.setState({
[target.name]: target.value
});
this.props.onEnter(target.value);
};
render() {
return (
<div className="Header">
<div>
<input
onChange={this.handleChange}
name="filter-results"
className="full"
type="text"
placeholder="search kks"
/>
</div>
<div>
<button className="full">SEARCH</button>
</div>
</div>
);
}
}
I am learning React and I am trying to call a function in a child component, that accesses a property that was passed from parent component and display it.
The props receives a "todo" object that has 2 properties, one of them is text.
I have tried to display the text directly without a function, like {this.props.todo.text} but it does not appear. I also tried like the code shows, by calling a function that returns the text.
This is my App.js
import React, { Component } from "react";
import NavBar from "./components/NavBar";
import "./App.css";
import TodoList from "./components/todoList";
import TodoElement from "./components/todoElement";
class App extends Component {
constructor(props) {
super(props);
this.state = {
todos: []
};
this.addNewTodo = this.addNewTodo.bind(this);
}
addNewTodo(input) {
const newTodo = {
text: input,
done: false
};
const todos = [...this.state.todos];
todos.push(newTodo);
this.setState({ todos });
}
render() {
return (
<div className="App">
<input type="text" id="text" />
<button
onClick={() => this.addNewTodo(document.getElementById("text"))}
>
Add new
</button>
{this.state.todos.map(todo => (
<TodoElement key={todo.text} todo={todo} />
))}
</div>
);
}
}
export default App;
This is my todoElement.jsx
import React, { Component } from "react";
class TodoElement extends Component {
state = {};
writeText() {
const texto = this.props.todo.text;
return texto;
}
render() {
return (
<div className="row">
<input type="checkbox" />
<p id={this.writeText()>{this.writeText()}</p>
<button>x</button>
</div>
);
}
}
export default TodoElement;
I expect that when I write in the input box, and press add, it will display the text.
From documentation
Refs provide a way to access DOM nodes or React elements created in the render method.
I'll write it as:
class App extends Component {
constructor(props) {
super(props);
this.state = {
todos: []
};
this.textRef = React.createRef();
this.addNewTodo = this.addNewTodo.bind(this);
}
addNewTodo() {
const newTodo = {
text: this.textRef.current.value,
done: false
};
const todos = [...this.state.todos, newTodo];
this.setState({ todos });
}
render() {
return (
<div className="App">
<input type="text" id="text" ref={this.textRef} />
<button onClick={this.addNewTodo}>Add new</button>
{this.state.todos.map(todo => (
<TodoElement key={todo.text} todo={todo} />
))}
</div>
);
}
}
In your approach, what you got as an argument to the parameter input of the method addNewTodo is an Element object. It is not the value you entered into the text field. To get the value, you need to call input.value. But this is approach is not we encourage in React, rather we use Ref when need to access the html native dom.
I am trying to update the text field as it is being typed on the input field
Here what I have done so far
constructor() {
super();
this.state = {
text: ""
};
}
changeText(evt){
let txt = this.state.text ;
txt = evt.target.value
this.setState({
text: txt
})
}
render() {
return(
<div>
<input name="option" type="text" onPress={(evt) => changeText(evt)}/>
<div>{this.state.text}</div>
</div>
)
}
There is no result showing up as I update the input element
You need to do this way.
it's easy to read and reusable.
the state will be created on the name of the form element.
import React, { Component } from 'react';
import { render } from 'react-dom';
import Hello from './Hello';
import './style.css';
class App extends Component{
constructor() {
super();
this.state = {
option: ""
};
}
changeText = evt =>{
this.setState({[evt.target.name]:evt.target.value})
}
render() {
return(
<div>
<input name="option" type="text" value={this.state.option} onChange={this.changeText} />
<div>{this.state.option}</div>
</div>
)
}
}
render(<App />, document.getElementById('root'));
You have to set the value of input to the state <input name="option" type="text" value={this.state.text} onPress={(evt) => changeText(evt)}/>
Check this stackblitz
https://stackblitz.com/edit/react-ntkqxw
you need to change onPress to onChange & changeText(evt) to this.changeText(evt)
You can use onChangeText inside your input field and then use the state value wherever you want to show it, like:
onChangeText{(value)=>this.setState({text: value })}
import React, { Component } from 'react';
import './App.css';
class App extends Component {
constructor(props) {
super(props);
this.state = {
items: []
}
}
addItem(e) {
var itemArray = this.state.items;
itemArray.push({
text: this._inputElement.value,
key: Date.now()
});
this.setState({
items: itemArray
});
e.preventDefault();
}
render() {
return (
<div className="main">
<div className="header">
<form onSubmit={this.addItem}>
<input ref={(a) => this._inputElement = a}
placeholder="enter your message"/>
<button type="submit">add</button>
</form>
</div>
<todoItems entries={this.state.items}></todoItems>
</div>
);
}
}
class todoItems extends Component {
todoEntries = this.props.entries;
createTasks(item) {
return <li key={item.key}>{item.text}</li>
}
listItems = this.todoEntries.map(this.createTasks);
render() {
return(
<ul className="theList">
{this.listItems}
</ul>
);
}
}
export default App;
I try to make 'todo' app in react.js,
but it is not working add message.
it occurs refresh, and error console message :
bundle.js:30031 Warning: Unknown prop entries on tag.
Remove this prop from the element.
How do I should fix it ?
React components have to start with an upper-case letter otherwise it will not be recognized as such. Should be
<TodoItems.../>