Copy div content on button click in React - javascript

I want to copy the div content on button click.
import React from 'react';
const App = () => {
const copyCode = () => {
//TODO
}
const data = "www.test.com";
const srcCode = `<script src=${data}></script>`;
return (
<>
<div>
{srcCode}
</div>
<button onClick={copyCode}>
Copy
</button>
</>
);
}
export default App;

This could be simple using react-copy-to-clipboard library
const data = "www.test.com";
const srcCode = `<script src=${data}></script>`;
return (
<>
<div>{srcCode}</div>
<br />
<CopyToClipboard text={srcCode} onCopy={() => alert("copied")}>
<button>Copy</button>
</CopyToClipboard>
</>
);
Codesandbox for demo

Related

Get JSX from imported React Component

For the purposes of documenting our library, I want to convert a React Component function to JSX. For example, if we have a rendered Button component, I want to show the code for how it's constructed.
One solution could be to read Button.jsx as plain text but I feel like there should be a better solution.
// Button.jsx
export const Button = (props) => (
<button {...props}><Icon name={props.icon}/>{props.children}</button>
)
// ButtonDocs.jsx
import { Button } from 'components/Button';
const Docs = (props) => {
const renderedButton = <Button icon='home'>Hello</Button>
// Here I'd expect this function to return something like:
// `<button><Icon name="home"/>Hello</button>`
const buttonJSX = someFunctionToGetJSX(renderedButton)
return (
<div>
{renderedButton}
<code>
{buttonJSX}
</code>
</div>
)
}
Do this in Button component
const Button = (props) => {
const buttonRef = useRef();
const [jsxEl, setJsxEl] = useState("");
useEffect(() => {
let jsxArray = [];
for (let i = 0; i < buttonRef.current.children.length; i++) {
jsxArray.push(`${buttonRef.current.children[i].innerHTML}`);
}
jsxArray.join(",");
setJsxEl(jsxArray);
props.onJsxFunc(jsxEl);
}, [buttonRef]);
return (
<Fragment>
<div ref={buttonRef}>
<button {...props}>
<Icon name={props.icon} />
{props.children}
</button>
</div>
</Fragment>
);
};
export default Button;
Then in ButtonDocs component do the below.
// ButtonDocs.jsx
import { Button } from 'components/Button';
const Docs = (props) => {
const renderedButton = <Button onJsxFunc={(el) => showJsxElements(el)} icon='home'>Hello</Button>
const jsxCode = useRef();
const showJsxElements = (el) => {
jsxCode.current.innerText += `${el}`;
};
return (
<div>
{renderedButton}
<code>
<div ref={jsxCode}></div>
</code>
</div>
)
}

Display file name after selecting it

I want to create a button on my site that will allow the user to upload a file from their device (computer, phone).
I have already made this button and it opens a window where you can select a file.
But I ran into a problem: I would like to display the name of this file on the page.
I have this component highlighted in orange:
export default function BoxForChoiceFile() {
return (
<Card sx={styles.CommonStyle}>
<SelectFileButton></SelectFileButton>
</Card>
);
}
And in the BoxForChoiceFile component there is a button for choosing a file
export default function SelectFileButton() {
const fileInput = useRef();
const selectFile = () => {
fileInput.current.click();
}
return (
<div>
<input type="file" style={{ "display": "none" }} ref={fileInput} />
<Button onClick={selectFile} className='btn btn-primary' sx={styles.DispositionBottom}>
<span>Upload</span>
</Button>
</div>
)
}
In addition to what Alberto Anderick Jr answered, this is how you can pass the file name from the child component to the father component and show it below SelectFileComponent, in your BoxForChoiceFile :
export default function BoxForChoiceFile() {
const [fileName, setFileName] = useState("");
return (
<div>
<Card sx={styles.CommonStyle}>
<SelectFileButton setFileName={setFileName} />
</Card>
<h5>{fileName}</h5>
</div>
);
}
and in your SelectFileComponent:
export default function SelectFileButton(props) {
const {setFileName} = props;
const [file, setFile] = useState(null);
const fileInput = useRef();
const selectFile = () => {
fileInput.current.click();
};
const updateName = () => {
setFile(fileInput.current.files[0]);
setFileName(fileInput.current.files[0]?.name);
}
return (
<div>
<input type="file" style={{ display: "none" }} ref={fileInput} onChange={updateName} />
<button onClick={selectFile} className="btn btn-primary">
<span>Upload</span>
</button>
</div>
);
}
This is an example of how you can capture the name of the file selected into a state:
import { useRef, useState } from "react";
export default function SelectFileButton() {
const [fileName, setFileName] = useState("");
const fileInput = useRef();
const selectFile = () => {
fileInput.current.click();
};
const updateName = () => {
setFileName(fileInput.current.files[0]?.name);
}
return (
<div>
<input type="file" style={{ display: "none" }} ref={fileInput} onChange={updateName} />
<button onClick={selectFile} className="btn btn-primary">
<span>Upload</span>
</button>
<h5>{fileName}</h5>
</div>
);
}
This code can definitely be improved depending on your case, but it should give you what you want.

How to click programmatically a child component? react

I have two components, the parent and child. Currently I have these codes below. But unfortunately it returns an error:
TypeError: Cannot read property 'click' of null
For some reasons I want when button is click the Item component also will be click. But these codes below produces an error above. Anyone does know how to achieve it?
import React, { useRef } from 'react';
const App = (props) => {
const itemRef = useRef(null);
return (
<div>
{dynamicBoolean ? (
<button onClick={() => itemRef.current.click()}>
click item
</button>
) : (
//more codes here
<Item ref={itemRef} />
)}
</div>
);
};
export default App;
Child component would look like below (demonstration purposes, the code is very lengthly)
import React from 'react';
const Item = (props) => {
return (
<div>
//some design here
</div>
);
};
export default Item;
You need useRef and you have to forward this ref to the Item component.
import React, { forwardRef, useRef } from 'react';
const Item = forwardRef((props, ref) => {
return <li {...props}
onClick={() => alert('clicked on Item')}
ref={ref} >MyItem</li>
})
const App = (props) => {
const itemRef = useRef(null);
return (
<div>
<button onClick={() => itemRef.current.click()}>
click item
</button>
<Item ref={itemRef} />
</div>
);
};
export default App;
import React, { createRef } from "react";
const Hello = (props) => {
const itemRef = createRef();
const hello = () => {
itemRef.current.click();
};
return (
<div>
<button onClick={() => hello()}>click item</button>
<Item ref={itemRef} />
</div>
);
};
const Item = React.forwardRef((props, ref) => {
const myClick = () => {
console.log("this is clicked");
};
return (
<button ref={ref} className="FancyButton" onClick={myClick}>
{props.children}
</button>
);
});
export default Hello;

How do I pass the ID of the button pressed to the parent component?

I'm trying to create a simple component that displays a group of buttons such that when one of the buttons is pressed, the parent knows the ID of that button. I have written some code, but I'm stuck as to the final step to identify which of the buttons is pressed. Any help would be appreciated. Thanks!
function GroupofButtons(props) {
const groupofBtns = [];
props.btns.forEach((btn) => {
groupofBtns.push(<button id={btn} value={btn} key={btn} onClick={() => props.onClick()}>{btn}</button>)
}
);
return(
<>
{groupofBtns}
</>
)
}
function App() {
// How can the console show the id of the button that was pressed
const handleClick = () => console.log("pressed");
const btn_typs = [1,2,3,];
return (
<>Press a button!
<div>
<GroupofButtons btns={btn_typs} onClick={() => handleClick()}/>
</div>
</>
)
}
ReactDOM.render(
<App />,
document.getElementById('root')
);
Something like this:
import React from "react";
import "./styles.css";
const btn_typs = [1, 2, 3];
export default function App() {
const handleClick = (e) => {
console.log(e.target.name);
};
return (
<>
Press a button!
<div>
<GroupofButtons btns={btn_typs} handleClick={handleClick} />
</div>
</>
);
}
function GroupofButtons(props) {
return props.btns.map((btn, i) => (
<button name={btn} key={i} onClick={props.handleClick}>
{btn}
</button>
));
}
Heres the codepen: https://codesandbox.io/s/suspicious-firefly-czvct?file=/src/App.js

React - Rerender component on click of button which resides outside of component

I have index.js file where I have rendered the App component .
Index.js file
ReactDOM.render(<App />, document.getElementById('root'));
Below is the code for SettingContainer.js file where I have SettingContainer component. I have a button on click of it I need to rerender <SettingContainer value="10" /> But It doesn't render with defaultvalues.
SettingContainer.js file:
import React from 'react';
const SettingContainer = (props) => {
const [state, setState] = React.useState({
currentValue: props.value
});
const handleChange = (event) => {
setState({ currentValue: event.target.value });
};
return (
<React.Fragment>
<input type='text' value={state.currentValue} onChange={handleChange} />
</React.Fragment>
)
};
export default SettingContainer;
Below is the code for the App.js file where I have App component.
App.js file
const handleClick = () => {
ReactDOM.render(<SettingContainer value="10" />, document.getElementById('divHello'));
};
const App = () => {
return (
<>
<div id="divHello">
<SettingContainer value="10" />
</div>
<button onClick={handleClick}>Button</button>
</>
);
};
export default App;
Actually, your issue comes back to your mindset, you should change your thoughts about ReactJS. you should have an Index container like below:
const Index = () => {
const [isRender, renderSettingContainer] = useState(false);
return (
<>
{isRender && (
<SettingContainer />
)}
<App onClick={renderSettingContainer}>
</>;
);
};
Then, pass the onClick function from props to the App like below:
const App = ({ onClick }) => (
<>
Hello Friends
<div id="divHello">
</div>
<button onClick={onClick}>Button</button>
</>
);
Also, there is no need to use ReactDOM twice, so write it like below:
ReactDOM.render(<Index />, document.getElementById('root'));
If you have any questions, write a comment, definitely, I will answer and will change my answer.
Hint: the <></> is just like <React.Fragment></React.Fragment> with less code and better performance, based on Dan Abramov idea.
Use conditional rendering, on press button set value to display Hello component.
const Hello = () => (<p>Hello</p>)
Then in App set value to true on button press.
const App = () => {
const [displayHello, setDisplayHello] = useState(false);
const handleClick = () => {
setDisplayHello(!displayHello)
};
return (
<React.Fragment>
Hello Friends
<div id="divHello">
</div>
{displayHello && <Hello />}
<button onClick={handleClick}>Button</button>
</React.Fragment>
);
};
// Get a hook function
const {useState} = React;
const Hello = () => (<p style={{ backgroundColor: 'green', color: 'white'}}>Hi from Hello Component</p>)
const App = () => {
const [displayHello, setDisplayHello] = useState(false);
const handleClick = () => {
setDisplayHello(!displayHello)
};
return (
<React.Fragment>
Hello Friends
<div id="divHello">
</div>
{displayHello && <Hello />}
<button onClick={handleClick}>Button</button>
</React.Fragment>
);
};
// Render it
ReactDOM.render(
<App />,
document.getElementById("react")
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.4/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.4/umd/react-dom.production.min.js"></script>
<div id="react"></div>

Categories