Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Static value as hook input

I have a fetching service that fetches new data asynchronously and I want to update a component when new data is fetched.

To simplify things, assume this is my setup:

class SomeService {
  static data;

  // can be called by other components (asynchronous)
  static fetchData = async () => {
    data = await someAsynchronousCall() // data gets a new value
  };
}

const HomeScreen = () => {
  useEffect(() => {
    console.log('new data is: ' + SomeService.data);
  }, [SomeService.data]); // I want to trigger this once data changes

  return <View> ... </View>
};

I've tried something like this, but when data changes, the useEffect doesn't get called.

Is there a way to get the desired behaviour?

like image 411
Volodymyr Bobyr Avatar asked Jan 09 '20 02:01

Volodymyr Bobyr


People also ask

Does React hook work with static typing?

Do Hooks work with static typing? Hooks were designed with static typing in mind. Because they're functions, they are easier to type correctly than patterns like higher-order components. The latest Flow and TypeScript React definitions include support for React Hooks.

Why is Forstate not updating immediately?

The answer: They're just queues setState , and React. useState create queues for React core to update the state object of a React component. So the process to update React state is asynchronous for performance reasons. That's why changes don't feel immediate.

How do you get the input value from a hook in React?

Solution: Writing an input with React hooks useInput() will accept an argument called opts , which will allow the developer to pass other input type of properties. Inside useInput() I will create a state hook that will contain the value of the input element and it will be updated onChange event listener .

How to get input value from react hooks?

Using React Hooks to Get Input Value 1 First Step. Lets open up project file then open App.js file, there you can start by importing react and hooks useState so we can use it later. 2 Second Step. There we define name, setName. ... 3 Third Step. We need to provide return inside our App component so it will display something to the screen. ...

How do I use hooks to display state values?

To explore Hooks, you’ll make a product page with a shopping cart, then display the initial values based on the state. By the end of the step, you’ll know the different ways to hold a state value using Hooks and when to use state rather than a prop or a static value. Start by creating a directory for a Product component:

How to import hooks into multiple components?

Since Hooks are functions, you can import them into multiple components rather then using inheritance or other complex forms of class composition. In this step, you learned to set state using the current state.

What is the best way to handle an input with hooks?

What is more preferable or proper way to handle an input with hooks? Which would you use? 1) The simplest hook to handle input, but more fields you have, more repetitive code you have to write. const [username, setUsername] = useState (''); const [password, setPassword] = useState ('');


Video Answer


3 Answers

useEffect listen to state update. SomeService.data is a static variable. You should implement something like that using Hooks.

const HomeScreen = () => {
  const [data, setData] = useState();
  //Stand for componentDidMount (empty array dependancies)
  useEffect(()=>{
    setData(new SomeService());
  },[])
  useEffect(() => {
    console.log('new data is: ' + data);
  }, [data]); // I want to trigger this once data changes

  return <View> ... </View>
};
like image 190
David Desjardins Avatar answered Oct 14 '22 04:10

David Desjardins


useEffect run after every render by default (if there is no second parameter). And the second parameter of useEffect is for checking if it should re-run or not, NOT trigger the useEffect to run.

In your case, your static data may change, but there is nothing that makes your component re-render, so your useEffect function won't run.

You can make your data as state to make it re-render. Or somehow trigger re-render whenever your static data changes.

like image 21
Tan Dat Avatar answered Oct 14 '22 02:10

Tan Dat


You can use context api to separate your fetching logic from your component.

import React from 'react'
const DataContext = React.createContext()

function DataProvider({children}) {
  const [data, setData] = React.useState()
  React.useEffect(() => {
    const fetchData = async () => {
      const data = await someAsynchronousCall()
      setData(data)
    };
    fetchData()
  }, [])
  return (
    <DataContext.Provider value={data}>
        {children}
    </CountStateContext.Provider>
  )
}
export {DataProvider, DataContext}

In your component use useContext to get data

const HomeScreen = () => {
  const data = useContext(DataContext)
  useEffect(() => {
    console.log('new data is: ' + SomeService.data);
  }, [data]); // I want to trigger this once data changes

  return <View> ... </View>
};

and wrap your app in DataProvider

const App = props => {
<DataProvider>
  <HomeScreen />
  {/* other component */}
</DataProvider>
}
like image 1
Amit Chauhan Avatar answered Oct 14 '22 02:10

Amit Chauhan