How to connect this state array value to div element - reactjs

I am learning React and I am stuck on the following syntax.
class App extends React.Component{
constructor(){
super()
this.state = {
array: [1,2]
}
this.add = this.add.bind(this)
}
add(){
this.setState = {
array:[5,4]
}
}
render(){
const arr = this.state.array.map((val) => {
return val
});
///how to connect arr to div target_here
return(
<div>
<button onClick={this.add}>Button</button>
<div id="target_here"></div>
<button>Button</button>
</div>
)
}
}
ReactDOM.render(<App />, document.getElementById("app"))
My goal is to attach the const arr to the id target_here. This is sample syntax of the problem I am facing so I really appreciate solutions without changing the structure of the syntax. Help please?

Here's a working example of what you're trying to acomplish:
class App extends React.Component {
constructor(){
super()
this.state = {
array: [1,2]
}
this.add = this.add.bind(this)
}
add() {
this.setState({
array: [5,4]
})
}
render(){
const list = this.state.array.map(value => {
return <li>{value}</li>
});
return(
<div>
<button onClick={this.add}>Button</button>
<div id="list">
<ul>{list}</ul>
</div>
<button>Button</button>
</div>
)
}
}
ReactDOM.render(<App />, document.getElementById('app'))
JSFiddle Demo: https://jsfiddle.net/fwg2vz3u/1/

I didn't quite understand the problem exactly, but if you are trying to display the array, you would do:
return(
<div>
<button onClick={this.add}>Button</button>
<div id="target_here"></div>
{arr}
<button>Button</button>
</div>

Related

How to implement Reconciliation concept in react?

I want to add a string to my list and I have a CounterComponent that works separately from HelloWordComponent, I set 1 for 'Microsoft', 2 for 'FaceBook' and 3 for 'React'; when I add 'yahoo' to first of the list, Counter for 'yahoo' set to 1 and react turns to 0.
I know I have to use unique key and I think {name} is qualified, but I don't know where to use key = {name} exactly?
class HelloWordComponent extends React.Component {
render() {
return <div>{this.props.name}</div>
}
}
class Counter extends React.Component {
constructor(){
super()
this.onPlusClick = this.onPlusClick.bind(this)
this.state = {count : 0}
}
onPlusClick(){
this.setState(prevState => ({count: prevState.count + 1}))
}
render(){
return <div>
{this.state.count}
<button onClick = {this.onPlusClick}>+</button>
</div>
}
}
class App extends React.Component{
constructor(){
super()
this.addName = this.addName.bind(this)
this.state = {
name: "Sara",
list:['Microsoft', 'FaceBook', 'React']
}
}
addName(){
this.setState(prevState =>({list: ['Yahoo', ...prevState.list]}))
}
render(){
return (
<div >
{this.state.name}
{this.state.list.map(name =>{
return <div>
<HelloWordComponent key = {name} name = {name}/>
<Counter/>
</div>
})}
<br/>
<button onClick= {this.addName}>add a Name</button>
</div>
);
}
}
ReactDOM.render(<App/>,document.getElementById("app"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id="app"> </div>
I found the right solution of my problem, I have to set unique key (key = {name}) in my parent root element <div key = {name}> so the render method change to:
render(){
return (
<div >
{this.state.name}
{this.state.list.map(name =>{
return <div key = {name}>
<HelloWordComponent name = {name}/>
<Counter/>
</div>
})}

How to render multiple component in reactjs, what i'm doing wrong?

First i have a function to fetch data from database then
if the data be changed, i will create list components.
but it didnt work, what i'm doing wrong?
console:
class TweetContainer extends React.Component{
constructor(props){
super(props);
this.state = {
tweetData:{},
tweetRender : [],
listTweet:[]
}
}
here is my function to fetch data from database
componentDidMount(){
fetch('http://localhost:5000/tweet')
.then(function(response) {
return response.json();
})
.then(result=>{
this.setState({
tweetData: result
}, ()=>console.log(this.state.tweetData));
});
}
my function to make list component
componentDidUpdate(){
this.state.tweetRender = this.state.tweetData.data.slice(1,6);
console.log(this.state.tweetRender);
this.state.listTweet = this.state.tweetRender.map((tweet)=><Tweet
linkAvatar={'/image/jennyshen.jpg'}
name={"Vuongxuan"}
userName={'#vuggg'}
tweetText={tweet.content} />);
console.log(this.state.listTweet);
}
render(){
return(
<div id="main">
<h2>Tweet</h2>
<div id="stream">
{this.state.listTweet}
</div>
</div>
);
}
}
i dont know what i'm doing wrong.
Accordingly to React docs, componentDidMount lifecycle most common use is for:
Updating the DOM in response to prop or state changes.
And you want to get and render the tweets, right? Not necessarily listen to updates.
For now a solution is remove your componentDidUpdate() method and change your `render´ method to:
render(){
var tweetRender = this.state.tweetData.data.slice(1,6);
return(
<div id="main">
<h2>Tweet</h2>
<div id="stream">
{listTweet.map((tweet, idx) =>
<Tweet
key={idx}
linkAvatar={'/image/jennyshen.jpg'}
name={"Vuongxuan"}
userName={'#vuggg'}
tweetText={tweet.content} />
)}
</div>
</div>
);
}
It's generally not a good idea to put React elements (JSX) inside your component state. You could instead just store the data in state, and derive the JSX from that data in the render method.
Example
class TweetContainer extends React.Component {
state = {
tweetData: [],
tweetRender: [],
listTweet: []
};
componentDidMount() {
setTimeout(() => {
this.setState({
tweetData: [
{
id: 1,
name: "foo",
username: "#foo"
},
{
id: 2,
name: "bar",
username: "#bar"
}
]
});
}, 1000);
}
render() {
return (
<div id="main">
<h2>Tweet</h2>
<div id="stream">
{this.state.tweetData.map(obj => (
<div key={obj.id}>
{obj.username} - {obj.name}
</div>
))}
</div>
</div>
);
}
}
ReactDOM.render(<TweetContainer />, document.getElementById("root"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id="root"></div>

binding this and sending to handler

I know I can bind this in a couple of different ways in react like these:
<button onClick={this.onSelect.bind(this, data)}>Button</button>
or
<button onClick={() => this.onSelect(data)}>Button</button>
or
constructor(props) {
super(props);
this.onSelect= this.onSelect.bind(this)
}
<button onClick={this.onSelect}>Button</button>
The problem is that I cannot send data using third option. Is there anyway to use the third option and send data as well?
class App extends React.Component {
constructor(props) {
super(props);
this.onSelect = this.onSelect.bind(this);
}
onSelect(e) {
alert(e);
}
render() {
return (
<div className="App">
<h1>Hello CodeSandbox</h1>
<button onClick={event => this.onSelect(event)}>Button</button>
</div>
);
}
}
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, document.body);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id="root"></div>
You can use ES6 Arrow Function to send data here, it is called anonymous function calling:
constructor(props) {
super(props);
this.onSelect= this.onSelect.bind(this)
}
<button onClick={(event) => this.onSelect(event)}>Button</button>
Like this.
With the new arrow function brought by the ES6 syntax, you can forget about bind.
An arrow function will automatically bind to it's class context. Making your onSelect an arrow function will solve your problem.
To send your data, you can preconfigure your function to receive 2 sets of parameters, the first one being your data, and the second being the click event :
class App extends React.Component {
constructor(props) {
super(props);
this.state = { msg: '' }
}
onSelect = msg => event => {
this.setState({ msg })
}
render() {
const { msg } = this.state
return (
<div className="App">
<h3>{msg ? 'Yay, data : ' + msg : 'Click it !'}</h3>
<button onClick={this.onSelect('I sent data !')}>Button</button>
</div>
);
}
}
ReactDOM.render(<App />, document.getElementById("root"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.3.2/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.3.2/umd/react-dom.production.min.js"></script>
<div id="root"></div>

Why is my component not getting re-rendered upon using setState and changing the value of state?

Why is it that the component Eachcartitem is not getting re rendered although I change the state. I have this fucntion which gets called from inside the Eachcartitem component:-
cartremover(a){
var cart1=cart;
var firstpart=cart.slice(0,a);
var secondpart=cart.slice(a+1,cart.length);
var final = firstpart.concat(secondpart);
this.setState({
cartstate:final,
abc:true
})
}
The Eachcartitem is used as follows in parent component:-
<div style={{float:'left',width:'65%'}}>
{
this.state.cartstate.map((cat) => (<Eachcartitem data={cat} index={this.state.cartstate.indexOf(cat)} cartremover={i=>this.cartremover()}/>))
}
<br></br><br></br>
</div>
And the Eachcartitem is as follows:-
class Eachcartitem extends React.Component{
constructor(props){
super(props);
this.state={
data:this.props.data
};
}
clicker(){
this.props.cartremover(this.props.index);
}
render(){
return(
<div className='cartdiv'>
<div style={{width:'100%',display:'inline'}}>
<h3 style={{width:'70%',float:'left',paddingLeft:'10px'}}>{this.state.data.productName}</h3>
<div style={{float:'right'}}>Rs.{this.state.data.productPrice}</div>
<div style={{width:'30%',float:'left',paddingLeft:'10px'}}>Store:{this.state.data.shopName}</div>
<div style={{width:'30%',float:'left',paddingLeft:'10px'}}>Quantity:{this.state.data.productQuantity}</div>
<br></br><br></br><br></br><br></br><br></br>
<div style={{width:'auto',float:'left',paddingLeft:'10px'}}>Variant:{this.state.data.variant.quantity}</div>
<br></br><br></br><br></br><br></br>
<div style={{width:'auto',float:'right',marginRight:'7px'}} onClick={()=>this.clicker()}>❌</div>
</div>
</div>
);
}
}
export default Eachcartitem
But for some reason the cartitem divs are not getting changed why is it so?
Its because you are not passing the index of the item to the function, here:
cartremover={i => this.cartremover()}
Write it like this:
cartremover={i => this.cartremover(i)}
You don't need to pass the index to child component, use this code:
this.state.cartstate.map((cat, i) => (
<Eachcartitem data={cat} cartremover={e => this.cartremover(i)} />
))
Now from Eachcartitem simply call that method: this.props.cartremover().
Better to use splice to remove the element at particular index, write the method like this:
cartremover(a){
let cart = [...this.state.cartstate];
cart.splice(a, 1);
this.setState({
cartstate: cart,
abc: true
})
}
Check working snippet:
const Temp = (props) => <div>
{props.name}
<button onClick={props.cartremover}>Delete</button>
</div>
class App extends React.Component {
constructor() {
super()
this.state = {cart: ['a', 'b', 'c', 'd', 'e']}
}
cartremover(a){
let cart = [...this.state.cart];
cart.splice(a, 1);
this.setState({
cart,
})
}
render() {
return (
<div>
{this.state.cart.map((cart, i) => (
<Temp key={cart} name={cart} cartremover={e => this.cartremover(i)}/>
))}
</div>
)
}
}
ReactDOM.render(<App />, document.getElementById('app'))
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id='app' />

Unable to invoke props function passed to children in a loop reactjs

I am new to react. I am just trying to create a comment box and comment board which contain multiple comments.
Each comments have one inputbox, button(save,edit) and button(remove). I have passed function made in board named updateComment to Component Comment as props.
Now When I am trying to execute save of child function in which I have called parent function updateComment using this.props.updateComment
it is giving me error can't read property of undefined.
I have searched for similar question on stackoverflow but I am unable to solved this proplem.
My app.js code is as below.
import React from 'react';
import { Home } from './home.jsx';
class App extends React.Component {
render() {
return (
<div>
<Header/>
<Board />
</div>
);
}
}
class Header extends React.Component {
render() {
return (
<div>
<h1>Header</h1>
</div>
);
}
}
class Board extends React.Component {
constructor(props) {
super(props);
this.state = {
comments:[
"My name is brijesh",
"My name is santosh",
"My name is manoj"
]}
};
removeComment(i) {
console.log("going to remove element i",i);
var arr = this.state.comments;
arr.splice(i,1);
this.setState({comments:arr});
};
updateComment(newComment, i) {
var arr = this.state.comments;
arr[i] = newComment;
this.setState({comments:arr});
};
render() {
return (
<div className="board">
{
this.state.comments.map(function(text,i) {
return (
<Comment key ={i} index = {i}
updateComment={() => {this.updateComment}}
removeComment={() => {this.removeComment}}>
{text}
</Comment>
)
})
}
</div>
)
}
}
class Comment extends React.Component {
constructor(props) {
super(props);
this.state = {
edit: false
};
};
edit(){
this.setState({edit:true});
console.log("you clickced on edit0");
};
save(){
this.setState({edit:false});
var newText = this.refs.newText.value;
this.props.updateComment(newText, this.props.index);
console.log("you clickced on edit0",newText);
};
handleChange(event) {
this.setState({value: event.target.value});
}
render() {
if(this.state.edit) {
return (
<div>
<div className="comment">
<input type="text" ref="newText" defaultValue={this.props.children} onChange={ this.handleChange.bind(this) } />
<button onClick={this.save.bind(this)}>Save</button>
</div>
</div>
)
}
else {
return (
<div>
<div className="comment">
<div>{ this.props.children }</div>
<button onClick={this.edit.bind(this)}>Edit</button>
</div>
</div>
)
}
}
}
export default App
And my main.js looks like this.
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App.jsx';
ReactDOM.render(
( < App / > ), document.getElementById('app'));
I have also created fiddle also.
https://jsfiddle.net/aubrijesh/k3h2pcnj/#&togetherjs=uEI7TFnJD1
I believe that DOMZE is on the right track but you should also bind the function in the map statement. In my opinion arrow functions makes it much easier to keep track of what this refers to.
class Board extends React.Component {
constructor(props) {
super(props);
this.state = {
comments:[
"My name is brijesh",
"My name is santosh",
"My name is manoj"
]}
};
removeCommment(i) {
console.log("going to remove element i",i);
var arr = this.state.comments;
arr.splice(i,1);
this.setState({comments:arr});
};
updateComment(newComment, i) {
var arr = this.state.comments;
console.log("new Comment");
arr[i] = newComment;
this.setState({comments:arr});
};
render() {
return (
<div className="board">
{
this.state.comments.map((text,i) => {
return (
<Comment key ={i} index = {i}
updateComment={() => {this.updateComment}}
removeComment={() => {this.removeComment}}>
{text}
</Comment>
)
})
}
</div>
)
}
}
class Comment extends React.Component {
constructor(props) {
super(props);
this.state = {
edit: false
};
};
edit(){
this.setState({edit:true});
console.log("you clickced on edit0");
};
save(){
this.setState({edit:false});
var newText = this.refs.newText.value;
this.props.updateComment(newText, this.props.index);
console.log("you clickced on edit0",newText);
};
handleChange(event) {
this.setState({value: event.target.value});
}
render() {
if(this.state.edit) {
return (
<div>
<div className="comment">
<input type="text" ref="newText" defaultValue={this.props.children} onChange={ this.handleChange} />
<button onClick={this.save.bind(this)}>Save</button>
</div>
</div>
)
}
else {
return (
<div>
<div className="comment">
<div>{ this.props.children }</div>
<button onClick={this.edit.bind(this)}>Edit</button>
</div>
</div>
)
}
}
}
ReactDOM.render(<Board />, document.getElementById("app"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="app"></div>
update your render method
let self = this;
return (
<div className="board">
{
self.state.comments.map(function(text,i) {
return (
<Comment key ={i} index = {i}
updateComment={() => {self.updateComment}}
removeComment={() => {self.removeComment}}>
{text}
</Comment>
)
})
}
</div>
)
You need to bind the class to the function, so that it knows what "this" is
render() {
return (
<div className="board">
{
this.state.comments.map(function(text,i) {
return (
<Comment key ={i} index = {i}
updateComment={this.updateComment.bind(this)}
removeComment={this.removeComment.bind(this)}>
{text}
</Comment>
)
})
}
</div>
)
}
Note that you may want to do those bindings in the constructor so that it doesn't bind at each and every render

Resources