How can i re rendered reactjs component - reactjs

How can I update my state value inside child component in this property {this.state.username} using of this function this.messageSubmit and how can I re-render the child render for displaying changed state values. Please help me anyone how can I update my state value inside and chat box because I'm new to reactjs
This is my child component chatting.js
import React from "react";
export class Chatting extends React.Component{
constructor(props){
super(props);
this.state={
username: 'shiva'
}
this.messageSubmit=this.messageSubmit.bind(this);
this.messageTextBox=this.messageTextBox.bind(this);
}
messageTextBox(event){
this.setState=({
username :event.target.value
})
}
messageSubmit(){
console.log(this.setState.username);
}
render(){
return(
<div>
<div className="chat-decription">
<div className="rt">
<div className="talk-bubble tri-right btm-right">
<div className="talktext">
<p>Flush to the bottom right. Uses .btm-right only.</p>
</div>
</div>
</div>
<div className="fl">
<div className="talk-bubble tri-right btm-right">
<div className="talktext">
<p>Flush to the bottom right. Uses .btm-right only.</p>
</div>
</div>
</div>
<div className="rt">
<div className="talk-bubble tri-right btm-right">
<div className="talktext">
<p> {this.setState.username}</p>
</div>
</div>
</div>
<div className="fl">
<div className="talk-bubble tri-right btm-right">
<div className="talktext">
<p>Flush to the bottom right. Uses .btm-right only.</p>
</div>
</div>
</div>
</div>
<div className="chat-textfiled">
<input type="text" className="form-control text-form" onChange={this.messageTextBox}/>
<input type="button" value="submit" onClick={this.messageSubmit}/>
</div>
</div>
)
}
}
This is my parent class
import React from "react";
import {render} from "react-dom";
import {Default} from "./component/Default";
import {Chatting} from "./component/Chatting";
import {BrowserRouter as Router,Route,Link,Switch } from 'react-router-dom';
// import Background from '../images/person_img.png';
class App extends React.Component{
constructor(){
super();
}
render(){
return(
<Router>
<div className="container">
<div className="container-top">
<div className="col-lg-4 leftmenu-contact-bg">
<div className="searchbox">
<div className="textbox-bg">
<input type="text" className="form-control" placeholder="Search"/>
</div>
</div>
<div className="ex1">
<a href="/chattting">
<div className="left-list">
<div className="left-img"><i className="material-icons icon-color">person</i></div>
<div className="right-content">dgfg</div>
</div>
</a>
</div>
</div>
<div className="col-lg-8 row">
<Switch>
<Route exact path='/' component={Default} />
<Route exact path='/chattting' component={Chatting} />
</Switch>
</div>
</div>
</div>
</Router>
);
}
}
render(<App/>,document.getElementById('app'));

setState is a function.
You should write:
this.setState({
username: event.target.value
});
Also, instead of
console.log(this.setState.username);
You should write
console.log(this.state.username);
And, again, instead of:
<p>{this.setState.username}</p>
You should write
<p>{this.state.username}</p>

In addition to the syntax corrections by #Rahamin, couple of pointers to your code -
Calling setState in the render function directly shouldn't be used, as it'll go into an infinite recursive function call stack. You'll probably be thrown an error of Maximum update depth exceeded.
Also, using console.logdirectly in the function that sets the state won't give you the desired output as they are queued and updated. It's best to include such console.log statements in the render itself.
Lastly, please post questions with good formatted code :)

Related

Trying to append an API value to a controlled input field with React Hooks

When the component loads, I am making an axios call to a Geolocation API. If the user agrees to let the app get their location, it gets their zipcode. I am then trying to append the zipcode to the zipcode input field, but I can't figure out how to do it. This is my landing page.
import React, { useState, useEffect, useRef } from 'react';
import './App.scss';
import axios from 'axios';
import { FontAwesomeIcon } from '#fortawesome/react-fontawesome';
import { faBars } from '#fortawesome/free-solid-svg-icons';
import LandingPage from './components/landingPage';
function App() {
const[zipcode, setZipcode] = useState();
useEffect(() => {
axios({
"method":"GET",
"url":"https://find-any-ip-address-or-domain-location-world-wide.p.rapidapi.com/iplocation",
"headers":{
"content-type":"application/octet-stream",
"x-rapidapi-host":"find-any-ip-address-or-domain-location-world-wide.p.rapidapi.com",
"x-rapidapi-key":x-rapidapi-key,
"useQueryString":true
},
"params":{
"apikey":apikey
}
})
.then((response)=>{
console.log(response.data.zipCode);
setZipcode(response.data.zipCode);
})
.catch((error)=>{
console.log(error)
});
},[]);
return (
<div className="App" path='/'>
<header className='container'>
<div className='row'>
<div className='col-1'>
<button>
<h1><FontAwesomeIcon icon={faBars} /></h1>
</button>
</div>
<div className='col'>
<h1>MDNight</h1>
</div>
</div>
</header>
<LandingPage zipcode={zipcode} setZipcode={setZipcode} />
<footer className='container'>
<h2>Copyright 2020</h2>
</footer>
</div>
);
}
export default App;
And here is the child component.
import React, { useState, useEffect } from 'react';
import axios from 'axios';
function LandingPage(props) {
function handleInputChange(e) {
props.setZipcode(e.target.value);
};
return (
<main className='container'>
<div className='row'>
<div className='col'>
<h1>Welcome to <span>MDNight</span>!</h1>
<h2>The website that makes your date night more convenient.</h2>
<p>Let's assume that you and your "Significant Other" would like to go out for a date night, however, you have to continually switch back and forth between websites looking at showtimes and trying to find a place to eat beforehand. Well, that's where <span>MDNight</span> comes in! We take your location, movie you're interested in seeing, , and show you theaters that are showing your movie, and a list of restaurants nearby. Sound Convenient to you? Enter your info below to get started!</p>
</div>
</div>
<div className='row'>
<div className='col'>
<label htmlFor='zipcodeInput'>Please Enter Your zipcode to get started!</label>
</div>
</div>
<div className='row'>
<div className='col'>
<input name='zipcodeInput' type="text" value={props.zipcode} onChange={handleInputChange} />
</div>
</div>
<div className='row'>
<div className='col'>
<button className='btn btn-primary'>Get Started!</button>
</div>
</div>
</main>
);
}
export default LandingPage;
I've only ever used useState and useEffect, so I don't know if one of the other hooks solves this problem, but if someone could show me how that would be amazing.
I found this answer from someone on a React FB group. I added defaultValue={props.zipcode} to the input and it worked perfectly. I did not know about defaultValue until today.
You do not need zipcode as a dependency of the useEffect hook in the App component. I would suggest having an empty array as your dependency array because you want this hook to run on mount only.

how to meteor react subscribe data bind in component?

I am setting up a new meteor react app which subscribes new data from the server. I want to only bind data to main page component. I have following code main page componen.
import React from 'react';
import ReactDOM from 'react-dom';
import RealTime from '../../../lib/client/RealTime';
// TrackerReact is imported (default) with Meteor 1.3 new module system
import TrackerReact from 'meteor/ultimatejs:tracker-react';
import Game from '../pages/components/game';
// > React.Component is simply wrapped with TrackerReact
class MainPage extends TrackerReact(React.Component) {
// Note: In ES6, constructor() === componentWillMount() in React ES5
constructor() {
super();
this.state = {
subscription: {
tasks: Meteor.subscribe('userData')
},
data:{}
}
}
getingData(){
let data=RealTime.find().fetch();
return data;
}
render() {
const gamedata=this.getingData();
console.log(this.getingData());
return (
<div className="container ">
<div className="board-player-top">
<img className="user-pic" src="../../../../../images/player-img-top.png" alt="" title=""/>
<div className="board-player-userTagline">
<div className="user-tagline-component">
Black Name
<i>2202<img src="../../../../../images/user-flag.png" alt=""/></i>
</div>
<div className="captured-pieces">
<img src="images/small-picW-1.png" /> <img src="images/small-picW-2.png" />
</div>
<div className="clock-top">
10:00
</div>
</div>
</div>
<Game/>
<div className="board-player-bottom">
<img className="user-pic" src="../../../images/player-img-bottom.png" alt="" title=""/>
<div className="board-player-userTagline">
<div className="user-tagline-component">
Staick <i>1576<img src="../../../images/user-flag.png" alt=""/></i>
</div>
<div className="captured-pieces">
<img src="images/small-picB-1.png" /> <img src="images/small-picB-2.png" />
</div>
<div className="clock-bottom active">
10:00
</div>
</div>
</div>
</div>
)
}
};
export default MainPage
i have console.log(this.getingData()) inside render found
following data from serverside which automatically update.
Application comminucation with help of socket io other server and data publish to meteor client.application layout is following structer
You can pass data to child component using props but here you can find problem each time you have received the gamedata pass as props to child component then child component will update.
You should simantanilious pass data to each child component.

React : Parsing error: Unterminated JSX contents

I keep getting this syntax error, but have no idea where the end sequence is failing:
import React, { Component } from 'react';
import './App.css';
class App extends Component {
render() {
return (
<div className="App">
<textarea rows="4" cols="50">
<h1>Look at this!</h1>
<h2>This is MAGIC!</h2>
<a href="https://www.mozilla.com/">
<p>Think about all this power of <code>React</code></p>
<textarea />
</div>
);
}
}
export default App;
The <a> element is not closed. I suggest you to add linters it will be easier for you to spot these errors, also it's strange why you editor didn't point that.
You have two unterminated JSX contents in your code. One for the first textarea and one for the a. Here is the fixed code. By the way, I agree with the linter suggestion.
class App extends React.Component {
render() {
return (
<div className="App">
<textarea rows="4" cols="50" />
<h1>Look at this!</h1>
<h2>This is MAGIC!</h2>
Go to Mozilla
<p>
Think about all this power of <code>React</code>
</p>
<textarea />
</div>
);
}
}
ReactDOM.render( <App />, document.getElementById( "root" ) );
<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="root"></div>
html <a> tag needs to be closed using </a> if there is any content like text, div, etc.
Go to Mozilla

How to make filter by name and address in React.js

I'm new with React.js. I'm making filter by name and address but I don't know how to do this with separate components. I have main component Speakers - in this component I receive json and send this data to Filter and List. In List.js I get data and display all speaker items(all json). In Filter I want to make search by name and address. I don't know how to bind component filter and list. I'll appreciate if you help me. I know that Redux help working with data in React but I want to understand how to do this without it.
enter image description here
Speakers.js
import React, {Component} from 'react';
import Filters from './Filters';
import List from './List';
class Speakers extends Component {
constructor(props) {
super(props);
this.state = {
isLoading: false,
items: []
}
}
componentDidMount() {
this.setState({isLoading: true});
fetch("https://randomapi.com/api/6de6abfedb24f889e0b5f675edc50deb?fmt=raw&sole")
.then(res => res.json())
.then(
(result) => {
this.setState({
items: result,
isLoading: false
});
console.log(result);
}
)
.catch(error => this.setState({ error, isLoading: false }));
}
render() {
return (
<div className="speakers">
<div className="container-fluid">
<Filters getItems={this.state} />
<List getItems={this.state} />
</div>
</div>
);
}
}
export default Speakers;
List.js
import React, {Component} from 'react';
class List extends Component {
render() {
const {items, isLoading} = this.props.getItems;
if (isLoading) {
return <p>Loading ...</p>;
}
return (
<div className="speakers__list">
<div className="row">
{items.map((item, index) => (
<div className="col-md-3" key={index}>
<div className="card form-group shadow">
<div className="card-body text-center">
<h5 className="card-title">{item.first} {item.last}</h5>
<p>{item.email}</p>
<p>{item.address}</p>
<p>{item.balance}</p>
<p>{item.created}</p>
</div>
</div>
</div>
))}
</div>
</div>
)
}
}
export default List;
Filters.js
import React, {Component} from 'react';
class Filters extends Component {
render() {
return (
<div className="filters">
<div className="alert shadow">
<form>
<div className="container-fluid">
<div className="row">
<div className="col-md-5">
<label>Name/Surname</label>
<input type="text" className="form-control" />
</div>
<div className="col-md-5">
<label>Address</label>
<input type="text" className="form-control"/>
</div>
<div className="col-md-2 align-self-center text-center">
<button className="btn btn-primary">Search</button>
</div>
</div>
</div>
</form>
</div>
</div>
);
}
}
export default Filters;
One way to move forward (possibly the best way, IMO) is this:
Come up with a data model to describe a single "filter". This could be as simple as an object that describes a name string and an address string that items need to be filtered using. The design of this is up to you; pick whatever works out best.
Then, build two sets of behavior into Speakers:
The ability to receive filtration instructions from Filters. You can achieve this by writing a function in Speakers that acts as a callback function when something changes in Filters. Pass this function as a prop to Filters and have Filters call it when its state changes (meaning, when you get user interaction).
The ability to send this filter object to List. Every time the callback function is called, have Speakers send it down to List. You can achieve this by storing what Filters sends back in Speakers' state and passing that state item down to List as a prop. That should update List's props every time Filters calls the callback function and thus affects Speakers' state.
Then, build behavior in List such that it changes its rendering behavior based on this filter object. Make sure to detect props updates so that it works on the fly.

Can only update a mounted or mounting component. due to Router

I want to write a musicplayer with react.js. After init works ths player well.
But once I change the site with router to music list, the console show me the error:
Can only update a mounted or mounting component. This usually means
you called setState() on an unmounted component. This is a no-op.
Please check the code for the Player component
I have marked the line in code.
I think, while I am changing the site, the player component may be unmounted. But wihtout the componentWillUnmount function, nothing different.
Here is my project.
Thanks in advance!
player.js
import React, {Component} from 'react';
import '../../styles/player.less';
import Progress from '../commen/progress.js';
import {Link} from 'react-router-dom';
let duration = null;
export default class Player extends Component {
constructor(props){
super(props);
this.state={
progress: 0,
volume: 0,
isPlay: true,
},
this.play=this.play.bind(this);
this.progressChangeHandler=this.progressChangeHandler.bind(this);
this.volumeChangeHandler=this.volumeChangeHandler.bind(this);
}
componentDidMount(){
$('#player').bind($.jPlayer.event.timeupdate,(e)=>{
duration = e.jPlayer.status.duration;//total duration of the song
this.setState({//here is the problem !!!!!!!!!!!!!!!!!!!!!!!
volume: e.jPlayer.options.volume*100,
progress:e.jPlayer.status.currentPercentAbsolute
});//how lange already played
});
}
componentWillUnMount(){
//$('#player').unbind($.jPlayer.event.timeupdate);
}
//从子组件中获得值
//change progress
progressChangeHandler(progress){
$('#player').jPlayer('play', duration * progress);
}
//change volume
volumeChangeHandler(progress){
$('#player').jPlayer('volume', progress);
}
//play pause switcher
play(){
if(this.state.isPlay){
$('#player').jPlayer('pause');
}else{
$('#player').jPlayer('play');
}
this.setState({
isPlay: !this.state.isPlay,
})
}
render(){
return(
<div className="player-page">
<h1 className="caption">
<Link to="/list">My Favorite Music</Link>
</h1>
<div className="mt20 row">
<div className = "controll-wrapper">
<h2 className="music-title">{this.props.currentMusicItem.title}</h2>
<h3 className="music-artist mt10">{this.props.currentMusicItem.artist}</h3>
<div className="row mt20">
<div className="left-time -col-auto">-2:00</div>
<div className="volume-container">
<i className="icon-volume rt"></i>
<div className="volume-wrapper">
<Progress
progress={this.state.volume}
onProgressChange={this.volumeChangeHandler}
barColor="#aaa"></Progress>
</div>
</div>
</div>
<div className="progress-container">
<Progress
progress={this.state.progress}
onProgressChange={this.progressChangeHandler}>
</Progress>
</div>
<div className="mt35 row">
<div>
<i className="icon prev"></i>
<i className={`icon ml20 ${this.state.isPlay ? 'pause' : 'play'}`} onClick={this.play}></i>
<i className="icon next ml20"></i>
</div>
<div className="-col-auto">
<i className="icon repeat-cycle"></i>
</div>
</div>
</div>
<div className="-col-auto cover">
<img src={this.props.currentMusicItem.cover} alt={this.props.currentMusicItem.title}/>
</div>
</div>
</div>
/**<div className="player-page">
<Progress progress={this.state.progress} onProgressChange={this.progressChangeHandler}></Progress>
</div>**/
)
}
}
root.js
import React, {Component} from 'react';
import Header from './commen/header.js';
import Player from './page/player.js';
import {MUSIC_LIST} from '../config/musiclist';
import MusicListUI from './page/musiclistui.js';
import {BrowserRouter as Router, Switch, Route, Link} from 'react-router-dom';
export default class Root extends Component{
constructor(props){
super(props);
this.state={
musiclist: MUSIC_LIST,
currentMusicItem: MUSIC_LIST[0]
}
}
componentDidMount(){
$('#player').jPlayer({
ready:function(){
$(this).jPlayer('setMedia',{
mp3:'http://oj4t8z2d5.bkt.clouddn.com/%E9%AD%94%E9%AC%BC%E4%B8%AD%E7%9A%84%E5%A4%A9%E4%BD%BF.mp3'
}).jPlayer('play');
},
supplied:'mp3',
wmode: 'window'
});
}
render(){
const Home=() => (
<Player
currentMusicItem={this.state.currentMusicItem}
/>
);
const List = () => (
<MusicListUI
currentMusicItem={this.state.currentMusicItem}
musiclist={this.state.musiclist}
/>
);
return(
<Router>
<div>
<Header/>
<Switch>
<Route exact path="/" component={Home}/>
<Route path="/list" component={List}/>
</Switch>
</div>
</Router>
)
}
}
Error sums it up well. When you change the route component gets unmounted and callback tries to setState on unmounted component. You have to figure out how to do clean up before this happens. I see you already figured out that you can use componentWillUnmount, but you have a typo:
componentWillUnMount(){ // should be componentWillUnmount!
//$('#player').unbind($.jPlayer.event.timeupdate);
}
Notice also that bind method has been deprecated.
Router is not your issue. Your issue is that you are fighting a fundamental design paradigm of React... or perhaps common sense. You are not supposed to try and perform operations on components that don't currently don't exist. What would that accomplish? In your case, you have a bunch of event listeners that you haven't removed.
As a side note, you are using an incredible amount of jQuery. You should be using this.setState as often as you can. You're programming in a style that goes against some of the best aspects of React.

Resources