Conditional Rendering,use-timeout Invalid hook call React - reactjs

When check is true I want to display Next button.I get errors like unexpected token,invalid hook call.
Please help me.Thanks in advance.
import React from "react";
import useTimeout from "use-timeout";
class App extends React.Component {
state = { check: true };
handleCheck = () => {
this.setState({ check: !this.state.check });
};
render() {
useTimeout(() => {
this.handleCheck();
}, 10000);
return (
<div>
{
if(this.state.check){
return <button>Next</button>
}
}
</div>
);
}
}
export default App;

do this instead:
<div> {this.state.check && <button>Next</button> </div>
and remove useTimeout you don't need it and you CANT use it either as it's a hook and you're using a class component. You should trigger it by onClick instead or if you insist on using a timeout use setTimeout but I wouldn't advise using that inside render
use a timeout like this:
componentDidmount() {
setTimeout(() => {
this.handleCheck();
}, 10000);
}

Related

How to select specific element in react.js

I want to select specific element with className "material-icons-outlined" and add new class to that element
In javascript i would do it like this
document.querySelectorAll(".material-icons-outlined").forEach(icon => {
icon.classList.add("notranslate");
})
But in react that doesn't work though, so how to do that in a react way?
You can still do that in React, just put those lines in useEffect:
useEffect(() => {
document.querySelectorAll(".material-icons-outlined").forEach((icon) => {
// check if already has the class
if (!icon.classList.contains("notranslate"))
icon.classList.add("notranslate");
});
});
Checkout ref or useRef in reactjs It is your answer.
class App extends React.Component {
componentDidMount() {
this.yourRef = React.createRef()
}
render() {
return (
<div>
<div id="divR" ref={this.yourRef}>...</div>
</div>
)
}
}

How can i use react-toastify from hook?

I found useToast and useToastContainer, but documentation is absent and i don't understand how tu use these hooks. Can anyone provide some info about these hooks?
The toasts inherit ToastContainer’s props. Props defined on toast supersede ToastContainer’s props.
There are two ways you can use toasts in your application:
1. Define ToastContainer inside the component
import { ToastContainer, toast } from 'react-toastify';
import 'react-toastify/dist/ReactToastify.css';
const App = () => {
notify = () => toast("Wow so easy !");
return (
<div>
<button onClick={notify}>Notify !</button>
// You can add <ToastContainer /> in root component as well.
<ToastContainer />
</div>
);
}
2. Call toast.configure() once in your app. At the root of your app is the best place.
The library will mount a ToastContainer for you if none is mounted.
import { toast } from "react-toastify";
import 'react-toastify/dist/ReactToastify.css';
// Call it once in your app. At the root of your app is the best place
toast.configure()
const App = () => {
notify = () => toast("Wow so easy !");
return (
<button onClick={notify}>Notify !</button>
);
}
You can use either of them. I prefer the 2nd method because you only need to define toast.configure() which is quite clean way to add it.
You can add configuration as per your need like below:
toast.configure({
autoClose: 8000,
draggable: false,
//etc you get the idea
});
EDIT
If you want to use toast hooks, then you must wrap your app with the ToastProvider to have access to its context elsewhere within your app.
import { ToastProvider, useToasts } from 'react-toast-notifications'
const FormWithToasts = () => {
const { addToast } = useToasts()
const onSubmit = async value => {
const { error } = await dataPersistenceLayer(value)
if (error) {
addToast(error.message, { appearance: 'error' })
} else {
addToast('Saved Successfully', { appearance: 'success' })
}
}
return <form onSubmit={onSubmit}>...</form>
}
const App = () => (
<ToastProvider>
<FormWithToasts />
</ToastProvider>
)

React Native - Create method in functional component and call this method outside of the component, possible?

I have a custom modal component:
export default ModalLoader = props=>{
const {
loading,
...attributes
} = props;
function closeModal(){
console.log('Close Modal Kepanggil coyyy!!!!!!!')
}
return(
<Modal
transparent={true}
animationType={'none'}
visible={loading}
>
<View>
<View>
<ActivityIndicator
size={'large'}
color={colors.darkRed}
/>
<CustomText style={{fontSize:24}}>Mohon Tunggu...</CustomText>
</View>
</View>
</Modal>
)
}
i want to used closeModal() in axios instance, so everytime axios get a response, i want to close modal in axios file itself not in all of my component,
let say my axios instance something like this:
AxiosHttp.interceptors.response.use((res)=>{
CustomLog(res.data, 'Interceptor')
// call closeModal of ModalLoader
ModalLoader.closeModal()
return res.data;
},(err)=>{
CustomLog(err, 'Interceptor Error')
// call closeModal of ModalLoader
ModalLoader.closeModal()
return Promise.reject(err)
})
export default AxiosHttp
is it possible to do that?
One way is to use React Context.
Create a context provider with the function you want to use to close/toggle the modal. Then in the ModalLoader (or any component of choice) use the function from that context.
./ModalContext.jsx
import React, { createContext } from 'react';
const ModalContext = createContext({
closeModal: () => {
console.log('Close Modal Kepanggil coyyy!!!!!!!');
},
});
export default ModalContext;
With the introduction of react-hooks in v16.8.0 you can use context in functional components using the useContext hook.
Axios instance
import React, { useContext } from 'react';
import { ModalContext } from './ModalContext';
const modalContext = useContext(ModalContext);
AxiosHttp.interceptors.response.use((res)=>{
CustomLog(res.data, 'Interceptor')
// call closeModal in context
modalContext.closeModal()
return res.data;
},(err)=>{
CustomLog(err, 'Interceptor Error')
// call closeModal in context
modalContext.closeModal()
return Promise.reject(err)
})
export default AxiosHttp;
See working example to play around with here: https://codepen.io/studiospindle/pen/xxxMRow
In that example there is a async function as an example which will close the modal window after three seconds. This is to mimic the Axios example. Also provided an example with a button.
a simple example on using react context as #Remi suggested
Core part is ModalContext.js. It exports the context for other components.
You can edit the state inside the provider if you need more common function/prop.
If you really need a static function to do so. You might need a manager
class ModalInstanceManager {
_defaultInstance = null;
register(_ref) {
if (!this._defaultInstance && "_id" in _ref) {
this._defaultInstance = _ref;
}
}
unregister(_ref) {
if (!!this._defaultInstance && this._defaultInstance._id === _ref._id) {
this._defaultInstance = null;
}
}
getDefault() {
return this._defaultInstance;
}
}
export default new ModalInstanceManager();
In your ModalLoader:
componentDidMount() {
ModalInstanceManager.register(this);
}
then in your static function:
ModalLoader.open/close = ()=> {
ModalInstanceManager.getDefault().open/close();
}

React this.setState not working with context API

Currently I have this code from my AppContext.js file
import React, { Component, createContext } from 'react';
export const AppContext = createContext();
export class AppProvider extends Component {
state = {
test: '',
};
getEntries() {
console.log('FIRED');
this.setState({test: 'HELLO'});
}
render() {
return (
<AppContext.Provider
value={{
...this.state,
getEntries: this.getEntries
}}
>
{this.props.children}
</AppContext.Provider>
);
}
}
I'm calling the getEntries function and its displaying message from the console successfully but the this.setState is not working it says TypeError: this.setState is not a function
The problem here is this is not bound to the right context.
The simplest workaround is probably to use this syntax:
getEntries = () => {
...
}
There are several ways in React to bind this to the class context: check this article for other ways.
getEntries function needs to be bind to the component. The simple way to do it is to use arrow function as shown below.
getEntries = () => {
console.log('FIRED');
this.setState({test: 'HELLO'});
}
The second way to bind getEnteries method to the component is
constructor(props) {
super(props);
// This binding is necessary to make `this` work in the callback
this.getEntries = this.getEntries.bind(this);
}

React - Wait for complex method to finish before rendering

I'm trying to display a dashboard component, crunching a lot of data fetched from my redux store. This component takes a lot of time to render, mainly because of a single complex method.
Is it possible to render some kind of loader or placeholder while this method is processing ?
I tried doing so by using ComponentDidMount, but it seems like, because the method is part of my render() method, it will always be triggered first-hand.
Yes! Check out this tutorial.
Loader:
import React, {Component} from 'react';
const asyncComponent = (importComponent) => {
return class extends Component {
state = {
component: null
}
componentDidMount() {
importComponent()
.then(cmp => {
this.setState({component: cmp.default});
});
}
render() {
const C = this.state.component;
return C ? <C {...this.props}/> : null;
}
}
};
export default asyncComponent;
Usage:
import React from 'react';
import asyncComponent from '../../hoc/asyncComponent';
const AsyncButton = asyncComponent(() => {
return import('../Button');
});
const container = () => {
return (
<div>
<h1>Here goes an async loaded button component</h1>
<AsyncButton/>
</div>
);
};
export default container;
or check out this library.

Resources