ReactPlayer full screen not working while onStart - reactjs

import React, { Component } from 'react'
import ReactPlayer from 'react-player'
class DailyPass extends Component {
constructor(props) {
super(props);
this.state = {
data:{},
popup: 2,
review:0
};
}
componentDidMount(){
let url = "http://127.0.0.1:8000/landing/";
fetch(url)
.then(response => response.json())
.then(data => {
this.setState ({
data:data[0]
})
})
}
makeFullscreen = () => {
document.getElementById('widget2').dblclick()
}
render () {
return (
<div>
<ReactPlayer
youtubeConfig={{ playerVars: { showinfo: 0 } }}
url={ this.state.data.url }
playing
width="100%" height="450px"
style={{ display:'block',marginLeft:'auto',marginRight:'auto' }}
id="player"
onStart = {() => this.makeFullscreen()}
controls="true"
/>
</div>
)
}
}
export default DailyPass
Here I am using react-player with react to embed the youtube video.
I want to make a video screen as a full screen by default.
so i am calling makeFullscreen() function onStart.
But it is not working.
I checked the documentation for onStart function so that I can make double click to make it full screen but, didn't work.
Please have a look

Related

React, How to use a menu in a seperate file to call an api and return data to a different section of the main file

I have a react app with a large menu, and as such am trying to move it to a seperate file from the main app.js
at the mement when you click on a link in the menu it call a node api and which returns some data, however when I try to seperate I can not get it to populate the results section which is still in the main script
Working version app.js
import React,{ useState } from 'react';
import './App.css';
import axios from 'axios';
import { Navigation } from "react-minimal-side-navigation";
import "react-minimal-side-navigation/lib/ReactMinimalSideNavigation.css";
export default class MyList extends React.Component {
constructor(props) {
super(props);
this.state = {
result: [],
};
this.callmyapi = this.callmyapi.bind(this);
}
render() {
return (
<div>
<div class="menu">
<Navigation
onSelect={({itemId}) => {
axios.get(`/api/menu/`, {
params: {
Menu: itemId,
}
})
.then(res => {
const results = res.data;
this.setState({ results });
})
.catch((err) => {
console.log(err);
})
}}
items={[
{
title: 'Pizza',
itemId: '/menu/Pizza/',
},
{
title: 'Cheese',
itemId: '/menu/cheese',
}
]}
/>
</div>
<div class="body">
this.state.results && this.state.results.map(results => <li>* {results.Name}</li>);
</div>
</div>
);
}
}
New app.js
import React,{ useState } from 'react';
import './App.css';
//import axios from 'axios';
//import { Navigation } from "react-minimal-side-navigation";
//import "react-minimal-side-navigation/lib/ReactMinimalSideNavigation.css";
import MyMenu from './mymenu';
export default class MyList extends React.Component {
constructor(props) {
super(props);
this.state = {
result: [],
};
this.callmyapi = this.callmyapi.bind(this);
}
render() {
return (
<div>
<div class="menu">
<MyMenu />
</div>
<div class="body">
this.state.results && this.state.results.map(results => <li>* {results.Name}</li>);
</div>
</div>
);
}
}
New menu file
mymenu.js
import React, { Component } from 'react';
import axios from 'axios';
import './App.css';
//import MyList from './App.js';
//import { ProSidebar, Menu, MenuItem, SubMenu } from 'react-pro-sidebar';
//import 'react-pro-sidebar/dist/css/styles.css';
import { Navigation } from "react-minimal-side-navigation";
//import Icon from "awesome-react-icons";
import "react-minimal-side-navigation/lib/ReactMinimalSideNavigation.css";
//export default async function MyMenu(){
export default class MyMenu extends React.Component {
constructor(props) {
super(props);
};
render() {
return (
<div>
<Navigation
// you can use your own router's api to get pathname
activeItemId="/management/members"
onSelect={({itemId}) => {
// return axios
axios.get(`/api/menu/`, {
params: {
// Menu: itemId,
Menu: "meat",
SubMenu : "burgers"
}
})
.then(res => {
const results = res.data;
this.setState({ results });
})
.catch((err) => {
console.log(err);
})
}}
items={[
{
title: 'Pizza',
itemId: '/menu/Pizza/',
},
{
title: 'Cheese',
itemId: '/menu/cheese',
}
]}
/>
</div>
);
}
}
Any help would be greatly appreciated
That one is quite easy once you understand state. State is component specific it that case. this.state refers to you App-Component and your Menu-Component individually. So in order for them to share one state you have to pass it down the component tree like this.
export default class MyList extends React.Component {
constructor(props) {
super(props);
this.state = {
result: [],
};
}
render() {
return (
<div>
<div class="menu">
<MyMenu handleStateChange={(results: any[]) => this.setState(results)} />
</div>
<div class="body">
this.state.results && this.state.results.map(results => <li>* {results.Name}</li>);
</div>
</div>
);
}
}
See this line: <MyMenu handleStateChange={(results: any[]) => this.setState(results)} />
There you pass a function to mutate the state of App-Component down to a the child
There you can call:
onSelect={({itemId}) => {
// return axios
axios.get(`/api/menu/`, {
params: {
// Menu: itemId,
Menu: "meat",
SubMenu : "burgers"
}
})
.then(res => {
const results = res.data;
this.props.handleStateChange(results)
})
.catch((err) => {
console.log(err);
})
You mutate the parent state and the correct data is being rendered. Make sure to practice state and how it works and how usefull patterns look like to share state between components.
Thanks - I Have found solution (also deleted link question)
above render added function
handleCallback = (results) =>{
this.setState({data: results})
}
then where I display the menu
<MyMenu parentCallback = {this.handleCallback}/>
where i display the results
{this.state.results && this.state.results.map(results => <li>{results.Name}</li>}
No aditional changes to the menu scripts

Dynamically loading Markdown file in React

I use markdown-to-jsx to render markdown in my React component.
My problem is that I want to dynamically load the markdown file, instead of specifying it with import. The scenario is that this happens on an article details page, i.e. I get the articleId from the route params and then based on that id, I want to load the corresponding markdown file, e.g. article-123.md.
Here's what I have so far. How can I load the md file dynamically?
import React, { Component } from 'react'
import Markdown from 'markdown-to-jsx';
import articleMd from './article-123.md'
class Article extends Component {
constructor(props) {
super(props)
this.state = { md: '' }
}
componentWillMount() {
fetch(articleMd)
.then((res) => res.text())
.then((md) => {
this.setState({ md })
})
}
render() {
return (
<div className="article">
<Markdown children={this.state.md}/>
</div>
)
}
}
export default Article
This works fine as is, but if I remove import articleMd from './article-123.md' at the top and instead pass the file path directly to fetch it output what looks like index.html, not the expected md file.
Can't you use dynamic import?
class Article extends React.Component {
constructor(props) {
super(props)
this.state = { md: '' }
}
async componentDidMount() {
const articleId = this.props.params.articleId; // or however you get your articleId
const file = await import(`./article-${articleId}.md`);
const response = await fetch(file.default);
const text = await response.text();
this.setState({
md: text
})
}
render() {
return (
<div className="article">
<Markdown children={this.state.md} />
</div>
)
}
}
I know this is an old thread but I just solved this issue with the following code
using markdown-to-jsx
import React, { Component } from 'react'
import Markdown from 'markdown-to-jsx'
class Markdown_parser extends Component {
constructor(props) {
super(props)
this.state = { md: "" }
}
componentWillMount() {
const { path } = this.props;
import(`${path}`).then((module)=>
fetch(module.default)
.then((res) => res.text())
.then((md) => {
this.setState({ md })
})
)
}
render() {
let { md } = this.state
return (
<div className="post">
<Markdown children={md} />
</div>
)
}
}
export default Markdown_parser
I then call the class sa follows
<Markdown_parser path = "path-to-your-fle" />

Getting props from parent component state to render data

I am building a weather app.
The behavior would be to have a Button in my main menu. This Button should display the current weather. When clicking this button it should display a card with all the weather informations. This is pretty similar to Momentum
I could successfully create my Weather Card displaying the current Weather and also the forecast.
My issue is I do not know how to display the weather in my button before I click on it to display weather. Not sure how to access my data and render it.
My SideMenu component displaying the Menu
export default class SideMenu extends React.Component {
constructor(props) {
super(props);
}
changeView(e, view) {
e.preventDefault();
this.props.changeView(view);
}
render() {
const { cityName } = this.props;
return (<Menu>
<Button onClick={(e) => this.changeView(e, "weather")}>
</Button>
<Button onClick={(e) => this.changeView(e, "todo")}>
ToDo
</Button>
<Button onClick={(e) => this.changeView(e, "pomodoro")}>
Pomo
</Button>
<Button onClick={(e) => this.changeView(e, "picture")}>
Info
</Button>
</Menu>);
}
}
The Weather Card component where I get the data from the API and render it
class WeatherCard extends Component {
constructor(props) {
super(props);
this.state = {
temperature: "",
latitude: "",
longitude: "",
summary: "",
cityName: "",
numForecastDays: 5,
isLoading: false
};
}
componentDidMount() {
this.getLocation();
}
// Use of APIXU API with latitude and longitude query
getWeather() {
const { latitude, longitude, numForecastDays } = this.state;
const URL = `https://api.apixu.com/v1/forecast.json?key=${KEY}&q=${latitude},${longitude}&days=${numForecastDays}`;
axios
.get(URL)
.then(res => {
const data = res.data;
this.setState({
cityName: data.location.name + ", " + data.location.region,
summary: data.current.condition.text,
temperature: data.current.temp_c,
forecastDays: data.forecast.forecastday,
iconURL: data.current.condition.icon
});
})
.catch(err => {
if (err) console.log(err);
});
}
// function using current longitude and latitude of user
// This requires authorization from user // Could be changed using IP adress instead, but would be less precise
getLocation() {
navigator.geolocation.getCurrentPosition(
position => {
this.setState(
prevState => ({
latitude: position.coords.latitude,
longitude: position.coords.longitude
}),
() => {
this.getWeather();
}
);
},
error => this.setState({ forecast: error.message }),
{ enableHighAccuracy: true, timeout: 20000, maximumAge: 1000 }
);
}
render() {
const {
summary,
temperature,
cityName,
iconURL,
forecastDays,
isLoading
} = this.state;
return (
<div>
{isLoading && (
<div>
<Spinner />
<LoaderText>Loading....</LoaderText>
</div>
)}
{!isLoading && (
<Wrapper>
<CurrentWeather
cityName={cityName}
summary={summary}
temperature={temperature}
icon={iconURL}
/>
<Forecast forecastDays={forecastDays} />
</Wrapper>
)}
</div>
);
}
}
export default WeatherCard;
You can control the display of you widget using the state.
You can pass a click handler to your sidemenu as a prop, once you click on an item you emit the click event to the parent component (with some payload if you want).
The parent component will have a handler method which is responsible for displaying your widget.
I've made some adjustments into you index.js and SideMenu.js files.
index.js
import React, { Component } from 'react';
import { render } from 'react-dom';
import WeatherCard from './Weather';
import SideMenu from './SideMenu';
class App extends Component {
constructor() {
super();
this.state = {
showWeather: false
}
}
handleItemClick = (item) => {
if (item === 'weather') {
this.setState({
showWeather: true
});
}
}
render() {
return (
<div>
<SideMenu onItemClick={this.handleItemClick} />
{this.state.showWeather ? <WeatherCard /> : null}
</div>
);
}
}
render(<App />, document.getElementById('root'));
SideMenu.js
export default class SideMenu extends React.Component {
constructor(props) {
super(props);
}
render() {
const { cityName } = this.props;
return (
<Menu>
<Button onClick={() => this.props.onItemClick('weather')}>
Open Weather Widget
</Button>
</Menu>
);
}
}
here is a fully working stacklitz with the adjustments mentioned above, hope that this will help.
If you want a data to be accessible by all the components, then you have these options:
React Context
Redux or MobX which are state management libraries.

React setState fetch API

I am starting to learn React and creating my second project at the moment. I am trying to usi MovieDb API to create a movie search app. Everything is fine when I get the initial list of movies. But onClick on each of the list items I want to show the details of each movie. I have created a few apps like this using vanilla JS and traditional XHR call. This time I am using fetch API which seems straightforward ans simply to use, however when I map through response data to get id of each movie in order to retrieve details separately for each of them I get the full list of details for all the items, which is not the desired effect. I put the list of objects into an array, because after setState in map I was only getting the details for the last element. I know that I am probably doing something wrong within the API call but it might as well be my whole REACT code. I would appreciate any help.
My code
App.js
import React, { Component } from 'react';
import SearchInput from './Components/SearchInput'
import './App.css';
class App extends Component {
constructor(props) {
super(props);
this.state =
{
value: '',
showComponent: false,
results: [],
images: {},
};
this.handleSubmit = this.handleSubmit.bind(this);
this.handleOnChange = this.handleOnChange.bind(this);
this.getImages = this.getImages.bind(this);
this.getData = this.getData.bind(this);
}
ComponentWillMount() {
this.getImages();
this.getData();
}
getImages(d) {
let request = 'https://api.themoviedb.org/3/configuration?api_key=70790634913a5fad270423eb23e97259'
fetch(request)
.then((response) => {
return response.json();
}).then((data) => {
this.setState({
images: data.images
});
});
}
getData() {
let request = new Request('https://api.themoviedb.org/3/search/movie?api_key=70790634913a5fad270423eb23e97259&query='+this.state.value+'');
fetch(request)
.then((response) => {
return response.json();
}).then((data) => {
this.setState({
results: data.results
});
});
}
handleOnChange(e) {
this.setState({value: e.target.value})
}
handleSubmit(e) {
e.preventDefault();
this.getImages();
this.setState({showComponent: true});
this.getData();
}
render() {
return (
<SearchInput handleSubmit={this.handleSubmit} handleOnChange={this.handleOnChange} results={this.state.results} images={this.state.images} value={this.state.value} showComponent={this.state.showComponent}/>
);
}
}
export default App;
SearchInput.js
import React, {Component} from 'react';
import MoviesList from './MoviesList';
class SearchInput extends Component {
render() {
return(
<div className='container'>
<form id='search-form' onSubmit={this.props.handleSubmit}>
<input value={this.props.value} onChange={this.props.handleOnChange} type='text' placeholder='Search movies, tv shows...' name='search-field' id='search-field' />
<button type='submit'>Search</button>
</form>
<ul>
{this.props.showComponent ?
<MoviesList value={this.props.value} results={this.props.results} images={this.props.images}/> : null
}
</ul>
</div>
)
}
}
export default SearchInput;
This is the component where I try to fetch details data
MovieList.js
import React, { Component } from 'react';
import MovieDetails from './MovieDetails';
let details = [];
class MoviesList extends Component {
constructor(props) {
super(props);
this.state = {
showComponent: false,
details: []
}
this.showDetails = this.showDetails.bind(this);
this.getDetails = this.getDetails.bind(this);
}
componentDidMount() {
this.getDetails();
}
getDetails() {
let request = new Request('https://api.themoviedb.org/3/search/movie?api_key=70790634913a5fad270423eb23e97259&query='+this.props.value+'');
fetch(request)
.then((response) => {
return response.json();
}).then((data) => {
data.results.forEach((result, i) => {
let url = 'https://api.themoviedb.org/3/movie/'+ result.id +'?api_key=70790634913a5fad270423eb23e97259&append_to_response=videos,images';
return fetch(url)
.then((response) => {
return response.json();
}).then((data) => {
details.push(data)
this.setState({details: details});
});
});
console.log(details);
});
}
showDetails(id) {
this.setState({showComponent: true}, () => {
console.log(this.state.details)
});
console.log(this.props.results)
}
render() {
let results;
let images = this.props.images;
results = this.props.results.map((result, index) => {
return(
<li ref={result.id} id={result.id} key={result.id} onClick={this.showDetails}>
{result.title}{result.id}
<img src={images.base_url +`${images.poster_sizes?images.poster_sizes[0]: 'err'}` + result.backdrop_path} alt=''/>
</li>
)
});
return (
<div>
{results}
<div>
{this.state.showComponent ? <MovieDetails details={this.state.details} results={this.props.results}/> : null}
</div>
</div>
)
}
}
export default MoviesList;
MovieDetails.js
import React, { Component } from 'react';
class MovieDetails extends Component {
render() {
let details;
details = this.props.details.map((detail,index) => {
if (this.props.results[index].id === detail.id) {
return(
<div key={detail.id}>
{this.props.results[index].id} {detail.id}
</div>
)} else {
console.log('err')
}
});
return(
<ul>
{details}
</ul>
)
}
}
export default MovieDetails;
Theres a lot going on here...
//Here you would attach an onclick listener and would fire your "get details about this specific movie function" sending through either, the id, or full result if you wish.
//Then you getDetails, would need to take an argument, (the id) which you could use to fetch one movie.
getDetails(id){
fetch(id)
displayresults, profit
}
results = this.props.results.map((result, index) => {
return(
<li onClick={() => this.getDetails(result.id) ref={result.id} id={result.id} key={result.id} onClick={this.showDetails}>
{result.title}{result.id}
<img src={images.base_url +`${images.poster_sizes?images.poster_sizes[0]: 'err'}` + result.backdrop_path} alt=''/>
</li>
)
});
Thanks for all the answers but I have actually maanged to sort it out with a bit of help from a friend. In my MovieList I returned a new Component called Movie for each component and there I make a call to API fro movie details using each of the movie details from my map function in MovieList component
Movielist
import React, { Component } from 'react';
import Movie from './Movie';
class MoviesList extends Component {
render() {
let results;
if(this.props.results) {
results = this.props.results.map((result, index) => {
return(
<Movie key={result.id} result={result} images={this.props.images}/>
)
});
}
return (
<div>
{results}
</div>
)
}
}
export default MoviesList;
Movie.js
import React, { Component } from 'react';
import MovieDetails from './MovieDetails';
class Movie extends Component {
constructor(props) {
super(props);
this.state = {
showComponent: false,
details: []
}
this.showDetails = this.showDetails.bind(this);
this.getDetails = this.getDetails.bind(this);
}
componentDidMount() {
this.getDetails();
}
getDetails() {
let request = new Request('https://api.themoviedb.org/3/search/movie?api_key=70790634913a5fad270423eb23e97259&query='+this.props.value+'');
fetch(request)
.then((response) => {
return response.json();
}).then((data) => {
let url = 'https://api.themoviedb.org/3/movie/'+ this.props.result.id +'?api_key=70790634913a5fad270423eb23e97259&append_to_response=videos,images';
return fetch(url)
}).then((response) => {
return response.json();
}).then((data) => {
this.setState({details: data});
});
}
showDetails(id) {
this.setState({showComponent: true}, () => {
console.log(this.state.details)
});
}
render() {
return(
<li ref={this.props.result.id} id={this.props.result.id} key={this.props.result.id} onClick={this.showDetails}>
{this.props.result.title}
<img src={this.props.images.base_url +`${this.props.images.poster_sizes?this.props.images.poster_sizes[0]: 'err'}` + this.props.result.backdrop_path} alt=''/>
{this.state.showComponent ? <MovieDetails details={this.state.details}/> : null}
</li>
)
}
}
export default Movie;

React TransitionGroup lifecycle methods not being called when component is loaded

I'm trying to animate a list entering and exiting with gsap, so I wrapped my list with <TransitionGroup>. I want to use componentWillEnter and componentWillLeave to trigger my animations, but they aren't being called. I've checked everything 1000x and can't figure it out... Should I be using <Transition> instead for this sort of animation?
import React from "react";
import { TransitionGroup } from "react-transition-group";
import animations from './animations';
class Events extends React.Component {
componentWillEnter(cb) {
console.log('entered');
const items = document.getElementsByClassName("items");
animations.animateIn(items, cb);
}
componentWillLeave(cb) {
console.log('exited');
const items = document.getElementsByClassName("items");
animations.animateOut(items, cb);
}
render() {
const event = this.props.event;
return (
<li key={event._id} className="items">
<h1>{event.title}</h1>
</li>
);
}
}
class Main extends React.Component {
constructor(props) {
super(props);
this.state = {
events: []
};
}
componentDidMount() {
return fetch("https://pickup-btown.herokuapp.com/api/event/biking",
{
method: "GET",
headers: {
"Content-Type": "application/json"
},
mode: "cors"
})
.then(response => {
return response.json();
})
.then(events => {
this.setState({ events: events.docs });
})
.catch(err => console.log(err));
}
unLoad(e) {
e.preventDefault();
this.setState({ events: [] });
}
render() {
const events = this.state.events;
return (
<section>
<button onClick={this.unLoad.bind(this)}>back</button>
<TransitionGroup component="ul">
{events.length ? (
events.map(event => {
return <Events event={event} key={event._id} />;
})
) : (
<div />
)}
</TransitionGroup>
</section>
);
}
}
export default Main;
Any help would be much appreciated!
Child component life cycle methods has been removed in current react-transition-group and you can use onEnter and onExit methods to achieve like in your Events component will be
class Events extends React.Component {
render() {
const event = this.props.event;
return (
<Transition
timeout={300}
key={event._id}
onEntering={el => console.log("Entering", el)}
onEnter={el => console.log("enter", el)}
onExit={el => console.log("exit", el)}
in={true}
>
<li
key={event._id}
className="items"
>
<h1>{event.title}</h1>
</li>
</Transition>
);
}
}
I have worked on your codesandbox also and its working. For detailed info please go through documentation.

Resources