I'm sorry if my question has already asked.
I am a beginner on react and I really want to learn how to do this and understand.
I use Firebase on my React.JS project and i want switch a part of header when the user has connected or not.
I think using the conditional-rendering but on the firebase function after the (if) does not allow me to do setState().. or i have an error
So I would be very happy if we could help me or give me a track of where to look for the answers !
class Header extends Component {
state={
connected: null
}
render(){
firebase.auth().onAuthStateChanged(function(user) {
if (user) {
} else {
}
});
return (
<div className="backgroundheader">
<div className="liensheader">
<a href="/" className="lili" style={{textDecoration: "none"}}>Home</a>
<a href="/event" className="lili" style={{textDecoration: "none"}}>Manifestations</a>
<a href="/commerces" className="lili" style={{textDecoration: "none"}}>Commerces</a>
<a href="/tips" className="lili" style={{textDecoration: "none"}}>Tips</a>
</div>
{/* options header when the user is disconnect */}
{/* <Deader /> */}
{/* options header when the user is connected */}
{/* <Ceader /> */}
</div>
);
}
};
export default Header;
Thank's you and sorry for my bad english :/
The onAuthStateChanged fires asynchronously, so you can't directly use it inside your render method. Whenever you have a situation like this, the solution is to put the asynchronous value into the state, and then use the state in the render method.
So something like:
class Header extends Component {
state={
connected: null
}
componentDidMount() {
firebase.auth().onAuthStateChanged(function(user) {
setState({ user: user });
});
}
render(){
return (
<div className="backgroundheader">
<div className="liensheader">
<a href="/" className="lili" style={{textDecoration: "none"}}>Home</a>
<a href="/event" className="lili" style={{textDecoration: "none"}}>Manifestations</a>
<a href="/commerces" className="lili" style={{textDecoration: "none"}}>Commerces</a>
<a href="/tips" className="lili" style={{textDecoration: "none"}}>Tips</a>
</div>
{ user ? <Deader /> : <Ceader /> }
</div>
);
}
};
export default Header;
Also see:
Firebase storage: download images to and put to img src in React map. The same problem of asynchronously loaded data, but then with getting the download URL of images in Cloud Storage.
How to update Firebase data to the React application in realtime. This highlights the same problem of asynchronously loaded data, but now with getting JSON data from the Realtime Database.
Related
I am in the process of working on a joke app, which I am building from scratch by myself with no tutorial. Right now, there is a component SportsJokesApi, that pulls in the data from a local json folder (SportsJokesData) I created. This is how it is set up:
const SportsJokesData = [
{
id: "1",
question: "What did the baseball glove say to the ball?",
answer: "Catch ya later!"
}
]
export default Sports Jokes Data
On the landing page, when the user selects the Sports Jokes category, they will be taken to a new page which will display jokes related to sports. Right now, you need to click the button (Click here for a joke) in order for the first joke to display. I would love for the first random joke to already be displaying when the user selects this category and gets taken to that page for the first time.
This is how I have the component set up. In my initial approach I created a separate function called getInitialJoke, which returns a random joke. Then in the render, I created a variable called const {initialJoke} which is this.getInitialJoke(); and then the joke would be displayed. Since state update is asynchronous, I did some safety checking by using initialjoke?.answer. When I go back and run the app, no joke appears and the text does not show up. However, I do see new divs with empty p tags on console. Does anyone know what could be wrong and how I can fix this? Again, I want a joke to already be displaying. The way it is set up in this component, you have to click on the Click Here for a Joke button in order to see the first joke.
import React from 'react'
import SportsJokesData from '../data/SportsJokesData';
import { Link } from 'react-router-dom';
import './Buttons.css';
const initialState = {
randomJoke: {}
};
class SportsJokesApi extends React.Component {
constructor(props) {
super(props);
this.getRandomJoke = this.getRandomJoke.bind(this);
this.state = initialState;
}
getInitialJoke() {
return SportsJokesData[(SportsJokesData.length * Math.random()) << 0];
}
getRandomJoke() {
this.setState({
randomJoke: SportsJokesData[(SportsJokesData.length * Math.random()) << 0]
});
}
render() {
const {randomJoke} = this.state;
const {initialJoke} = this.getInitialJoke();
return (
<React.Fragment >
<div>
<p>{initialJoke?.question}</p>
</div>
<div>
<p>{initialJoke?.answer}</p>
</div>
<div className="flex">
<p>{randomJoke.question}</p>
</div>
<div className="flex">
<p>{randomJoke.answer}</p>
</div>
<div className="flex">
<button class="btn joke" onClick = {this.getRandomJoke}>Click here for joke </button>
</div>
<div className="flex">
<Link to="/ProgrammingJokes">
<button className="btn programming">Programming Jokes</button>
</Link>
</div>
<div className="flex">
<Link to="/DadJokes">
<button className="btn dad">Dad Jokes</button>
</Link>
</div>
<div className="flex">
<Link to="/SpanishJokes">
<button className="btn spanish">Chistes en ñ</button>
</Link>
</div>
<div className="flex">
<Link to="/">
<button className="btn home">Home Page</button>
</Link>
</div>
</React.Fragment >
);
}
}
export default SportsJokesApi;
Perhaps you could call the initialJoke() function in one of the React lifeCycle Events, for example with something like this:
// Add this to your code fellow.
componentDidMount() {
this.getInitialJoke();
}
For more information on the life cycle events and how they work, have a look at this great article, buddy.
React: Component Lifecycle Events
I have the following js
App.js
<LayoutRoute
exact
path="/analysis/:id"
layout={MainLayout}
component={AnalysisPage}
/>
index.js
<IconWidget
title="companyA"
subtitle="Top Product Trade: Pen"
color="info"
onClick={()=>{window.location='analysis/companyA'}}
/>
analysis.js
function analysisPage({match}){
console.log(match)
return(
<div>
{"${match.params.id}"}
</div>
)
}
const AnalysisPage= () => {
return(
<div>
Company: {this.analysisPage}
</div>
export default AnalysisPage;
I have applied react router in the App.js which can redirect the website from index.js to analysis.js by pressing the button.
However, I would like to display the params to the div. I took reference from https://alligator.io/react/react-router-parameters however, it doesn't work. I would like to know what have I did wrong? Thank you so much
You have to provide the props:
Company: {this.analysisPage(this.props)}
So that match params could be used:
function analysisPage({match}){
You can try this
this.props.match.params.id
I have a menu in my React app, here's the Menu component:
class Menu extends React.Component {
constructor(props) {
super(props);
this.state = {
active: '/'
}
}
render() {
return (
<nav>
<ul className='list-inline'>
<li>
<Link to='/' style={this.state.active === '/' ? activeStyle : {}} onClick={this.handleClick.bind(this, '/')}>
Home
</Link>
</li>
<li>
<Link to='/contact' style={this.state.active === 'contact' ? activeStyle : {}} onClick={this.handleClick.bind(this, 'contact')}>
Contact
</Link>
</li>
)
}
}
export default Menu
When I click on a menu item, the clicked item will get higlighted (bold). But if I have in the URL some page (eg. http://localhost:3001/contact) and refresh the page, this Contact item in the menu will not be highlighted (because highlighting is made based on the onClick event).
I tried to parse the content of URL with import * as qs from 'query-string'; // for fetching the URL paramaters and then I tried to display the URL content:
console.log(qs.parse(location.search));
But the output is only {} instead of the desired contact (so I could highlight this item in the menu).
Thus, when a URL is loaded straight (without click on the respective menu item), how do I catch this situation and highlight the respective menu item?
Thank you
React router has a component for exactly this situation
https://reacttraining.com/react-router/web/api/NavLink
You can change the component from Link to NavLink and add the component will check the url in which you are.
<Link to='/contact' style={this.state.active === 'contact' ? activeStyle : {}} onClick={this.handleClick.bind(this, 'contact')}>
Contact
</Link>
<NavLink
to="/contact"
activeStyle={activeStyle}
>Contact</NavLink>
Also, you can check the URL params from the router instance:
https://reacttraining.com/react-router/web/example/url-params
I'm just messing right now with react and thought I would try to make an app that could search for tweets. I basically just follwed the npm twitter examples but I can't get it to work. Here's what I have:
import React, { Component } from 'react';
import Twitter from 'twitter';
import config from './config.js'
class App extends Component {
constructor(){
super();
this.Client = new Twitter(config);
this.searchTwitter = this.searchTwitter.bind(this);
}
searchTwitter(){
this.Client.get('search/tweets', {q: 'node.js'}, function(error, tweets, response) {
console.log(tweets);
});
}
render() {
return (
<div className="App">
<header className="App-header">
<img src={logo} className="App-logo" alt="logo" />
<h1 className="App-title">The Test App</h1>
</header>
<button style = {{height: "50px", width: "150px"}} onClick = {this.searchTwitter}> CLICK ME </button>
</div>
);
}
}
It's just a quick test where you click the button and it searches for tweets and logs them to the console. The problem is I just get 'undefined' every time and I have checked the keys and tokens so I don't think that's the issue.
I've never tried to use this API so any help is very appreciated
It seems that the twitter api doesn't support CORS request, So we cannot make any calls to the api through the browser, hence its not working for you.
Please refer to the below link for more details:
https://twittercommunity.com/t/will-twitter-api-support-cors-headers-soon/28276/4
Using React-Router's Link, I have a set up like so:
<Link to={...}>{this.props.live? "Live": "Not Live"}</Link>
Where if this.props.live gets passed in, I would like to simply display a text "Live" which will direct to a new page. If this.props.live is not passed in, want to display the text "Not Live" but remove the hyperlink from it/deactivate/disable it.
Is it possible to do so? I tried <div style={{pointerEvents: "none"}}>Not Live</div>, but does not work.
Will be upvoting and accepting answer. Thank you!
You should do this:
let component;
component=this.props.live? <Link to={...}> Live </Link>: <div> Not Live </div>
render() {
{component}
}
Cheers:)
this.props.live
? <Link to={...}> Live </Link>
: <div> Not Live </div>
You can prevent the page to be redirected using evt.preventDefault()
class MyComponent extends React.Component {
constructor(props) {
this.handleLinkClick = this.handleLinkClick.bind(this);
}
handleLinkClick(evt) {
if (!this.props.live) {
evt.preventDefault(); // will prevent redirection
}
}
render() {
<Link onClick={this.handleLinkClick} to={...}>
{this.props.live? "Live": "Not Live"}
</Link>
}
}
Shorthand but controversial version
<Link onClick={evt => !this.props.live && evt.preventDefault()} to={...}>
{this.props.live? "Live": "Not Live"}
</Link>
See the API docs