简体   繁体   English

如何使用 useState 钩子设置标记文本?

[英]How to use useState hook to set markup text?

I have a functional component with the following hook:-我有一个带有以下钩子的功能组件:-

const [imagePreview, setImagePreview] = useState('');

Later on, the change event, I have this:-后来,更改事件,我有这个:-

    if (imagePreviewUrl) {
  setImagePreview( (<div>
    <br/> <img src={imagePreviewUrl} alt="icon" width="200" /> 
    </div>));
}

Looks like it doesn't set anything.看起来它没有设置任何东西。 how do I set it?我该如何设置? I could do it as:-我可以这样做:-

  let imagePreview = null;
if (imagePreviewUrl) {
  imagePreview = (<div>
    <br/> <img src={imagePreviewUrl} alt="icon" width="200" /> 
    </div>);
}

But it is bit ugly.但是有点丑。 I think useState is the recommended way to do it.我认为 useState 是推荐的方法。

Update with more code:-更新更多代码:-

  const fileChangedHandler = event => {
setSelectedFile(event.target.files[0]);
let reader = new FileReader();
reader.onloadend = () => {
setImagePreviewUrl(reader.result);
}
reader.readAsDataURL(event.target.files[0])
if (imagePreviewUrl) {
// can't break into multiline, sytax error 
setImagePreview('(<div><br/> <img src={imagePreviewUrl} alt="icon" width="200" /> </div>)');

} }

return (
 <div>
 <label>Profile picture: </label>
  <input className="Column" type="file" accept="image/*" 
       onChange={(e) => {fileChangedHandler(e)}} />
  // I want to show the selected image here as preview before upload 
  { imagePreview }
  </div>
 )

Hopefully, I will give a clear understanding.希望我能给出一个清晰的理解。 What is my intention?我的意图是什么?

The reason you're having issues is because you're trying to access the state of imagePreviewUrl right after you update it with setImagePreviewUrl - this will not work .您遇到问题的原因是因为您试图在使用setImagePreviewUrl更新后立即访问imagePreviewUrl的状态 - 这将不起作用

const fileChangeHandler = (event) => {
  // ...
  reader.onloadend = () => {
    // this is asynchronous
    // so this definitely wouldn't get
    // executed before you get to the `if` statement below
    // also, `setImagePreviewUrl` is asynchronous as well
    setImagePreviewUrl(reader.result)
  }
  // ...
  if (imagePreviewUrl) {
    // the old value of imagePreviewUrl is being used
    // here, and since the initial value evaluates to 
    // `false`, the `setImagePreview` call below
    // never gets executed
  }
}

Your new value for imagePreviewUrl won't be available immediately because it's asynchronous, so you should probably create a separate hook that listens for changes to imagePreviewUrl and updates imagePreview .您的imagePreviewUrl新值不会立即可用,因为它是异步的,因此您可能应该创建一个单独的挂钩来侦听imagePreviewUrl更改并更新imagePreview

function App() {
  const [imagePreviewUrl, setImagePreviewUrl] = React.useState("");
  const [imagePreview, setImagePreview] = React.useState(null);

  const fileChangedHandler = () => {
    setImagePreviewUrl(
      "https://interactive-examples.mdn.mozilla.net/media/examples/grapefruit-slice-332-332.jpg"
    );
  };

  React.useEffect(() => {
    if (imagePreviewUrl !== "") {
      const image = (
        <div>
          <img alt="fruit" src={imagePreviewUrl} />
        </div>
      );
      setImagePreview(image);
    }
  }, [imagePreviewUrl]);

  return (
    <div className="App">
      <button type="button" onClick={fileChangedHandler}>
        Trigger file change handler.
      </button>
      {imagePreview}
    </div>
  );
}

Here's a working example:这是一个工作示例:

This is not a recommended approach, what you want is a conditional rendering :这不是推荐的方法,您想要的是 条件渲染

const [imagePreview, setImagePreview] = useState(false);

if (imagePreviewUrl) {
  setImagePreview(true);
}

return (
  imagePreview && (
    <div>
      <br /> <img src={imagePreviewUrl} alt="icon" width="200" />
    </div>
  )
);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM