2 ms·
a) that doesn't do the same thing (button != input) b) in React, it's extremely bad practice to mutate raw DOM elements programmatically (the idiomatic version
by lhorie 7y ago
a) that doesn't do the same thing (button != input)
b) in React, it's extremely bad practice to mutate raw DOM elements programmatically (the idiomatic version is to use some state management mechanism and bind the value via `<input value={value} />`, which incidentally would be broken by this code)
c) setState may be asynchronous, so you can run into nasty surprises (e.g. you can't focus a hidden element). Whereas in vanilla code, unhiding logic could be added in a predictable procedural and explicit manner, in React a naive call to .focus() in the event handler may noop because of React-rendering-pipeline-specific reasons and then we need to get into its more obscure APIs to fix it)
- ng12 7y agoAh, your code sample was incomplete so I was extrapolating. I'm assuming the complete code would be: const input = React.useRef(null); return ( <> <input ref={input} /> <button onClick={event => { input.current.value = "value"; input.current.focus(); sound.play(); }} > Button </button> </> ); Which is almost identical to how you would do it in vanilla JavaScript except you would grab input by a query selector and be less resilient against DOM mutation and your references becoming stale. To point b there's nothing wrong with having an uncontrolled input. React allows you to use the raw DOM API if you'd like. You only need to use controlled inputs if they buy you something, and then the rewrite is a small diff: const input = React.useRef(null); const [inputValue, setInputValue] = React.useState("") return ( <> <input ref={input} value={inputValue} /> <button onClick={event => { setInputValue("value"); input.current.focus(); sound.play(); }} > Button </button> </> ); This is adding a line of code (useState) but in this case it's buying you something -- you have full control of the value and are insulated against DOM updates. For point c I'm not sure what you're referring to. I can't think of a situation where React would drop your call to `input.focus()` on the floor. I just tried breaking it by spamming state updates and was unable to. The whole point of React is that it handles DOM updates seamlessly and I would be surprised if it didn't in this case.
- lhorie 7y agoSure, if you're using a ref and being careful not to bind `value` in JSX, you're fine. That's not what you were doing though. Here's a simplified demo showing a variation of the issue: https://codesandbox.io/s/react-example-bytg0 https://codesandbox.io/s/react-example-bytg0 As for controlled/uncontrolled inputs and refs/hooks: that's kinda my point. In order to declaratively wire things up in an idiomatic way in React, we've had to introduce a bunch of React APIs to the snippet just to express the equivalent of a "when you click me, focus that guy" action -> effect relationship, because otherwise that relationship is hard to express in terms of declarative state snapshots.
- ng12 7y agoYou've misspelled the handler, onClick is the correct casing. Fix that and it works. Also you don't need to use a ref -- if I were inclined I could have grabbed the element by a query selector. I'm not sure why I would though, as I mentioned using ref is better protection against DOM updates. > In order to declaratively wire things up in an idiomatic way in React, we've had to introduce a bunch of React APIs Yes, because declarative programming is the benefit not the cost. As I said, you don't have to do it declaratively -- you can always use built-in DOM APIs -- but most people in the front-end community have agreed that doing things declaratively and architecting a UI as a state machine instead of a giant tree of independently mutating bits is preferable. One of the biggest sources of bugs in jQuery projects is developers forgetting to keep the DOM in sync with the data. The benefit of doing things declaratively is you don't have to worry about it. Cutting that problem off at the source is an invaluable benefit.
- jonahx 7y agoHe knows. He's the author of https://mithril.js.org/ https://mithril.js.org/. It's a person well-steeped in the theory and benefits of declarative and functional programming taking a step back and looking at the supposed enemy with fresh eyes and a deeper perspective.
- sergeykish 7y agoSimple and clean, almost like DOM Level 0 <input id=input /> <button onclick=' input.value = "value"; input.focus(); sound.play(); ' > Button </button>
- pailhead 7y agoWhere does `input` even come from in your code? That's invalid syntax. Was it supposed to be `const foo = input =>{...}`? b) It's kind of a bad practice to mutate raw DOM elements programatically without react, if it leads to horrible spaghetti code further down the road