I have a large project with multiple files. I want a button to render the content of some other components upon clicking. I am trying to understand why the following does not work, and what could I do to make it work instead?
Index.js
import React from "react"; import ReactDOM from "react-dom"; import { unitState, setUnitState } from './changeUnit.js' function App() { return ( <div> <h1>{unitState}</h1> <button onClick={setUnitState("°C")}>°C</button> <button onClick={setUnitState("°F")}>°F</button> </div> ); } // ------ const rootElement = document.getElementById("root"); ReactDOM.render(<App />, rootElement);
changeUnit.js
export let unitState = "°C"; export function setUnitState(unit) { (unit==="°C") ? unitState="°C" : unitState="°F"; }
with codesandbox link here
Currently, upon clicking any of the buttons the text does not change. But the code does reach inside the setUnitState
method. I suspect that is because the main component is not rerendering. I tried to change my changeUnit.js
code to
import App from './index.js'; export let unitState = "°C"; export function setUnitState(unit) { (unit==="°C") ? unitState="°C" : unitState="°F"; App.forceUpdate(); }
but I get the error _index.default.update is not a method
.
I have tried to use the useState
hook from React but I just can’t make it work for the life of me. I have tried many combinations but it seems that I can’t return the setState
function as a return from the custom hook.
Does anyone know how I can solve this problem?
Advertisement
Answer
I’m not sure why you’re not using the useState
hook, or what went wrong with your custom hook.
With useState()
:
function App() { let [unitState, setUnitState] = React.useState('°C') return ( <div> <h1>{unitState}</h1> <button onClick={() => setUnitState('°C')}>°C</button> <button onClick={() => setUnitState('°F')}>°F</button> </div> ); } ReactDOM.render(<App />, document.getElementById('root'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.1/umd/react.production.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.1/umd/react-dom.production.min.js"></script> <div id="root"></div>
With custom hook:
function App() { let { unitState, setCelsius, setFahrenheit } = useSwitch() return ( <div> <h1>{unitState}</h1> <button onClick={setCelsius}>°C</button> <button onClick={setFahrenheit}>°F</button> </div> ); } function useSwitch() { let [unitState, setUnitState] = React.useState('°C') let setCelsius = () => setUnitState('°C') let setFahrenheit = () => setUnitState('°F') return { unitState, setCelsius, setFahrenheit } } ReactDOM.render(<App />, document.getElementById('root'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.1/umd/react.production.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.1/umd/react-dom.production.min.js"></script> <div id="root"></div>