从自定义挂钩导入的状态值未显示

Value of state imported from custom hook not showing

我创建了一个自定义挂钩,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;

我将这个自定义挂钩导入到我的其他两个组件中,FaceRecognition.js 和 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;

函数 onSubmitonImputChange 按预期工作 InputForm.js 并且 imgUrl 的值在函数 onSubmit 运行时记录在控制台上,因为预期的。但是作为字符串的 imgUrl 状态无法显示在上面我的 FaceRecognition.js 片段中的 h1 标签 <h1 className='white'>The url is {imgUrl} boy</h1> 之间,并且它也不能作为 src h1 标签下方的图像 <img width={'50%'} alt=''src={imgUrl}/>。这是我的问题。

尝试将您的 return 语句放在预测

的 .then 中

问题

React 钩子不会神奇地共享状态。您有此 Custom 函数的两个独立实例,每个实例都有自己的 useState 挂钩。我说“功能”是因为您还 mis-named 您的钩子。所有 React 钩子都应以“use-”前缀命名,以便 React 可以识别它并对其应用 Rules of Hooks

解决方案

如果您希望 useCustom 挂钩的单独实例共享状态,则需要将状态提升到要共享的公共组件。为此,您应该使用 React Context。

示例:

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;

用法:

使用 CustomProvider 组件包装您的应用。

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

...

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

在消费者中导入并使用 useCustom 挂钩。

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;