I installed react-mailchimp-subscribe and I want to change text button because my website is not written in English.
i putted this component into div className="pokemon" to have access to him like .pokemon > div > button and could have change styles. Now I want to change text.
I try to acces to him by using
useEffect(() = > {
document.addEventListener("load", function(){
(".pokemon>div>button").innerHtml("Wyślij")
}); }, [])
but I guess in my function is too many errors that it actually work.
You can update the button label using the state. Please refer the below code
import React, { useEffect, useState } from 'react'
export default function App() {
const [buttonLabel, setButtonLabel ] = useState("I'm Button");
useEffect(() => {
setButtonLabel("Wyślij")
}, [])
return (
<div className="pokemon">
<div>
<button> {buttonLabel}</button>
</div>
</div>
)
}
Here is the link to codesandbox environment
If you want to do it using dom, you can use the below code.
You have some minor syntax mistake.
useEffect(() = > {
document.addEventListener("load", function(){
document.querySelector(".pokemon").querySelector("div").querySelector("button").innerHTML = "Wyślij";
}); }, [])
Related
I have created a reproducible exam of my problem, I don't understand why after the setDefaultValue is called and the component is updated (you can see it's updated using the result of my console.log) If now I click on the reset button instead of the new defaultValue I see the old one.
Here is a link to the example showing this problem, I'll also paste the code here
https://codesandbox.io/s/wonderful-tree-wtsgb4?file=/src/App.js
import "./styles.css";
import {useState, useRef} from 'react';
import TextBox from './TextBox';
export default function App() {
const textboxAPI = useRef(null)
const [defaultValue ,setDefaultValue] = useState('First')
return (
<div className="App">
<div style={{fontWeight: 'bold'}}>To reproduce please first click on the default value button then on the reset button</div>
<TextBox getAPI={(api) => textboxAPI.current = api} defaultValue={defaultValue}/>
<button onClick={() => setDefaultValue('second')}>1- Click me to change default value to "second"</button>
<button onClick={() => textboxAPI.current.reset()}>2- Click me to call reset inside Textbox</button>
</div>
);
}
import {useEffect, useState} from 'react';
const TextBox = ({defaultValue, getAPI}) => {
const [value, setValue] = useState(defaultValue || '')
useEffect(() => {
if (getAPI) {
getAPI({
reset: reset,
})
}
}, [])
const reset = () => {
console.log('TextBox Reset DefaultValue', defaultValue)
setValue(defaultValue)
}
console.log('TextBox DefaultValue', defaultValue)
return <div>{value}</div>
}
export default TextBox;
To reproduce the problem:
1- Click on the first button to set a new defaultValue, see the console.log, you can see the defaultValue has changed inside the TextBox Component
2- Click the reset button, it calls the reset function inside TextBox but the default value logged there has the previous value!
Here you save in textboxAPI.current function reset but just one time after first render of TextBox component. Function reset has a defaultValue in a closure and its value is 'First' during first render. So each next time you call textboxAPI.current.reset(), you call the reset function with defaultValue==='First' in its closure.
But you parent component controls child state and React does not recommend to manage your logic like that.
[UPDATED]
That will fix your issue, but I don not recommend to organize a state logic like that:
const TextBox = ({defaultValue, getAPI}) => {
const [value, setValue] = useState(defaultValue || '')
const reset = () => {
console.log('TextBox Reset DefaultValue', defaultValue)
setValue(defaultValue)
}
if (getAPI) {
getAPI({
reset: reset,
})
}
console.log('TextBox DefaultValue', defaultValue)
return <div>{value}</div>
}
export default TextBox;
Based on what I learned from the comments I tried using Hooks but There were too many changes needed especially I had some issues with React.lazy so I tried to look for more solutions until I found that using a combination of forwardRef and useImperativeHandle I can export my reset function without changing my current structure and it works as it should, I thought that I should share my solution for anyone else who might be looking for an alternative solution to Hooks.
I'm trying to build a modal in react. When it's opened, the background or the body color must change to a darker one and the modal should open, when closed, everything must go back to normal.
I tried to achieve this by this method:
const [modalState, setModalState] = useState(false);
const [modalBg, setModalbg] = useState(false);
function handleClick() {
setModalState(true);
setModalbg(true);
}
return (
{
!modalState ?
null
: <Modal modalState = {setModalState}/>
}
{
!modalBg ?
document.body.style.backgoundColor = "ffff"
: document.body.style.backgoundColor = 'rgba(39, 38, 38, 0.616)'
}
<button onClick= {handleClick}>Open</button>
)
The problem is, that instead of changing color of the body, it just renders text to the page like '#fff' or 'red'. I don't know why that happens, can anyone help?
Thanks!
Your way isn't really the "React" way of handling modals. First of all, I can't stress enough the use of portals when creating modals. Do look this up to really understand what portals are and how they help you.
Moving on, you can create a modal component as shown below and trigger this component however you want, using a state. Just make sure to pass the setter of that state to the component as a prop, in my case setShowModal.
Your modal's background is contained in the div my-modal-container and you can change that however you wish.
import React, { useState, useEffect } from 'react';
import ReactDOM from 'react-dom';
const MyModal = ({setShowModal}) => {
const handleClose = () => {
setShowModal(false)
};
return ReactDOM.createPortal(
<div className='my-modal-container'>
<div class='my-modal-body'>
//Place all you modal body here
</div>
</div>,
document.getElementById('portal')
);
};
export default MyModal;
If you choose to you use portals as above, make sure you add <div id="portal"></div> in your index.html file right below <div id="root"></div>.
You should not set the background colour of the body in the return function. That is meant to return the JSX.
Try using a useEffect hook something like:
useEffect(() => {
if (modalBg) {
document.body.style.backgoundColor = "rgba(39, 38, 38, 0.616)";
} else {
document.body.style.backgoundColor = "ffff";
}
}, [modalBg]);
In my Remix app, I'm trying to conditionally display a UI widget, based on the value of a state variable. Here is my code.
import { useState } from "react";
import type { LinksFunction } from "remix";
import stylesUrl from "../styles/index.css";
export const links: LinksFunction = () => {
return [
{
rel: "stylesheet",
href: stylesUrl
}
];
};
export default function Index() {
const [isMenuOpen,setMenuOpen] = useState(false)
function toggleNav(){
window.alert("hh") // no alert is shown
console.log("hi") // no console statement is printed
setMenuOpen(!isMenuOpen)
}
return (
<div className="landing">
<button onClick={toggleNav}>test</button>
</div>
);
}
However, toggleNav function doesn't seem to be triggered on button click. I couldn't see any alert or output in the console.
I couldn't understand why it's not working. It would be great, if someone can point me out what I'm doing wrong here. TIA.
Ensure that you are rendering the Scripts component from Remix in the root route, without it you app will not load any JS client side.
See https://remix.run/docs/en/v1/api/remix#meta-links-scripts
I'm using a quill js component (a text editor) for Reactjs and I'm testing it to see all it's features.
I managed to build a editor with a toolbar, but now I have a doubt, how can I get everything the user typed and save it in my state? As I'll show you in the code if I console.log(the quillRef.current) I get a div and way inside it I have a p element which contains everything the user has typed. My idea is to place a button in the end, and when the user stops typing and clicks the button I store what they typed.
here's a link to the sandbox where I'm testing it:
codesandbox link
With quill.getText() function :
import React, { useState } from "react";
import { useQuill } from "react-quilljs";
export default () => {
const { quill, quillRef } = useQuill();
const [savedText, setSavedText] = useState("");
const handleSave = () => {
const text = quill.getText();
setSavedText(text);
};
return (
<div style={{ width: 500, height: 300 }}>
<button onClick={handleSave}>SAVE</button>
<div>Saved State : {savedText}</div>
<div ref={quillRef} />
</div>
);
};
Check on codesandbox : https://codesandbox.io/s/react-quilljsbasic-tt6pm?file=/src/App.js
Where's the right place to put code that interacts with the DOM in a gatsby site? I want to toggle the visibility of some components by adding/removing a class when another element is clicked.
The gatsby-browser.js file seems like it should contain this code but the API doesn't seem to call any of the functions after the DOM has loaded.
Similarly, using Helmet calls it too soon. Using window.onload never seems to trigger at all regardless of where it's included.
window.onload = function () {
// add event listener to the toggle control
}
Is there an event I can use to run my code when the DOM is ready?
Do you really need to wait for the DOM to be ready? When working in react you need to change the way you think about these things. For example you could add an on click that changes state and then reflect the state change in your classname prop.
Code Example:
import React, { useState } from "react"
const MyApp = () => {
const [visible, setVisible] = useState(true) // true is the initial state
return (
<div>
<div className={visible ? "visible-class" : "hidden-class"}>
My content
</div>
<button onClick={() => setVisible(!visible)}>Click me!</button>
</div>
)
}
export default MyApp
Or you could take it a step further and not even render that content to the DOM until you want to.
Example:
import React, { useState } from "react"
const MyApp = () => {
const [visible, setVisible] = useState(true) // true is the inital state
return (
<div>
<button onClick={() => setVisible(!visible)}>Click me!</button>
{visible && <div>My content here</div>}
</div>
)
}
export default MyApp
You can use the React cyclelife with componentDidMount().
This need to update your component like that :
import React from 'react'
class YourComponent extends React.Component {
componentDidMount() {
// Your Javascript function here
}
render() {
return(
<div className="YourComponentHere"></div>
)
}
}
export default YourComponent
Hope that help you!
If your component is a functional component, try using React Hook useEffect, which will guarantee the execution after the component is rendered.
import React, { useEffect } from 'react'
const MyComponent = () => {
useEffect(() => {
console.log("Document loaded");
});
return (
<main>
<text>Pretty much the component's body code around here</text>
</main>
)
}
export default MyComponent