1

I created a custom hook, Custom.js:

import React, {useState, useEffect} from 'react';
import Clarifai from 'clarifai';

const app = new Clarifai.App({
    apiKey: 'XXXXXXXXXXXXXX'
})

const Custom = () => {

    const [input, setInput] = useState('');
    const [imgUrl, setImgUrl] = useState('');

    function onInputChange (text) {
        setInput(text);
    }

    useEffect(()=>{  
        setImgUrl(input)
    }, [input])


    function onSubmit () {
        console.log('submitted');
        console.log(imgUrl)

        app.models.predict(Clarifai.COLOR_MODEL, "https://www.takemefishing.org/getmedia/bde1c54e-3a5f-4aa3-af1f-f2b99cd6f38d/best-fishing-times-facebook.jpg?width=1200&height=630&ext=.jpg").then(
        function(response) {
            console.log(response);
        },
        function(err) {
            // there was an error
        }
        );
    }

    return {input, imgUrl, onInputChange, onSubmit}
}
 
export default Custom;

I imported this custom hook into 2 of my other components, FaceRecognition.js and InputForm.js.

FaceRecognition.js:

import React from 'react';
import Custom from '../Custom';

const FaceRecognition = () => {
    const { imgUrl } = Custom();
function yes (){
    return console.log(imgUrl)
}
yes()

    return (
        <div>
            <h1 className='white'>The url is {ImgUrl} </h1>
            <img width={'50%'} alt=''src={imgUrl}/>
        </div>
    );
}
 
export default FaceRecognition;

ImportForm.js:

import React, {useState} from 'react';
import './InputForm.css'
import Custom from '../Custom';


const InputForm = () => {

    const { onInputChange, onSubmit } = Custom();

   

    return (
        <>
            <p className='txt f3'>Enter image link address</p>
            <div className='center flex w-70'>
                <input type='text' className='w-80 pa1' onChange={(e)=>onInputChange(e.target.value)}/>
                <button className='w-20 pa1 pointer' onClick={onSubmit}>Detect</button>
            </div>
        </>
    );
}
 
export default InputForm;

The functions onSubmit and onImputChange work as expected for InputForm.js and the value of imgUrl logs on the console when function onSubmit runs, as expected. But the imgUrl state which is a string fails to show up between the h1 tags <h1 className='white'>The url is {imgUrl} boy</h1> from my FaceRecognition.js snippet above, and it also doesn't work as the src of the image <img width={'50%'} alt=''src={imgUrl}/> below the h1 tag. This is my problem.

Drew Reese
  • 165,259
  • 14
  • 153
  • 181
joshua
  • 67
  • 1
  • 6

2 Answers2

0

try to put your return statement inside the .then of the predict

  • Your answer could be improved with additional supporting information. Please [edit] to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Mar 10 '22 at 00:29
0

Issue

React hooks don't magically share state. You've two separate instances of this Custom function, each with their own useState hook. I say "function" because you've also mis-named your hook. All React hooks should be named with a "use-" prefix so React can identify it and apply the Rules of Hooks against it.

Solution

If you want separate instances of your useCustom hook to share state then the state needs to be lifted to a common component to be shared. For this you should use a React Context.

Example:

import React, { createContext, useContext, useState, useEffect } from 'react';
import Clarifai from 'clarifai';

const app = new Clarifai.App({
    apiKey: 'XXXXXXXXX'
});

const CustomContext = createContext({
  input: '',
  imgUrl: '',
  onInputChange: () => {},
  onSubmit: () => {}
});

const useCustom = () => useContext(CustomContext);

const CustomProvider = ({ children }) => {
  const [input, setInput] = useState('');
  const [imgUrl, setImgUrl] = useState('');

  function onInputChange (text) {
    setInput(text);
  }

  useEffect(()=>{  
    setImgUrl(input);
  }, [input]);

  function onSubmit () {
    console.log('submitted');
    console.log(imgUrl);

    app.models.predict(
      Clarifai.COLOR_MODEL,
      "https://www.takemefishing.org/getmedia/bde1c54e-3a5f-4aa3-af1f-f2b99cd6f38d/best-fishing-times-facebook.jpg?width=1200&height=630&ext=.jpg"
    ).then(
      function(response) {
        console.log(response);
      },
      function(err) {
        // there was an error
      }
    );
  }

  return (
    <CustomContext.Provider value={{ input, imgUrl, onInputChange, onSubmit }}>
      {children}
    </CustomContext.Provider>
  );
}

export {
  CustomContext,
  useCustom
};
 
export default CustomProvider;

Usage:

Wrap your app with your CustomProvider component.

import CustomProvider from '../path/to/CustomProvider';

...

return (
  <CustomProvider>
    <App />
  </CustomProvider>
);

Import and use the useCustom hook in consumers.

import React from 'react';
import { useCustom } from '../path/to/CustomProvider';

const FaceRecognition = () => {
  const { imgUrl } = useCustom();

  useEffect(() => {
    console.log(imgUrl);
  });

  return (
    <div>
      <h1 className='white'>The url is {ImgUrl}</h1>
      <img width={'50%'} alt='' src={imgUrl}/>
    </div>
  );
}
 
export default FaceRecognition;

...

import React, {useState} from 'react';
import './InputForm.css'
import { useCustom } from '../path/to/CustomProvider';

const InputForm = () => {
  const { onInputChange, onSubmit } = useCustom();

  return (
    <>
      <p className='txt f3'>Enter image link address</p>
      <div className='center flex w-70'>
        <input
          type='text'
          className='w-80 pa1'
          onChange={(e) => onInputChange(e.target.value)}
        />
        <button
          className='w-20 pa1 pointer'
          onClick={onSubmit}
        >
          Detect
        </button>
      </div>
    </>
  );
}
 
export default InputForm;
Drew Reese
  • 165,259
  • 14
  • 153
  • 181