I'm trying to create a composed input text (joining 4 input components) but i'm not being able.
Everything seems to be OK and the only way I Have been able to show the input text is placing it in the render of the main React component (cardform). In the DOM explorer (chrome) the only componet I an empty cardNumberFullField
This is the HTML:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<script src="https://unpkg.com/react#15/dist/react.min.js"></script>
<script src="https://unpkg.com/react-dom#15/dist/react-dom.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/babel-standalone/6.24.0/babel.js"></script>
</head>
<body>
<div id="root"></div>
<script type="text/babel" src="script.js"></script>
</body>
</html>
This is the JS:
class CardForm extends React.Component {
constructor(props) {
super(props)
}
render() {
return (
<div>
<cardNumberFullField />
</div>
)
}
}
function cardNumberFullField() {
return (
<div>
<cardNumberInputField inputName="0" />
<cardNumberInputField inputName="1" />
<cardNumberInputField inputName="2" />
<cardNumberInputField inputName="3" />
</div>
)
}
function cardNumberInputField(props) {
return (
<div>
<input id={props.inputName} name={props.inputName} type="text" />
</div>
)
}
// Main render
ReactDOM.render(<CardForm />, document.getElementById("root"))
React custom components always needs to be in Capitalized. So cardNumberFullField should be CardNumberFullField, cardNumberInputField should be CardNumberInputField
Check Specifying The React Element Type.
The first part of a JSX tag determines the type of the React element.
Capitalized types indicate that the JSX tag is referring to a React
component. These tags get compiled into a direct reference to the
named variable, so if you use the JSX expression, Foo must be
in scope.
class CardForm extends React.Component {
constructor(props) {
super(props);
}
render() {
return (
<div>
<CardNumberFullField />
</div>
);
}
}
function CardNumberFullField() {
return (
<div>
<CardNumberInputField inputName="0" />
<CardNumberInputField inputName="1" />
<CardNumberInputField inputName="2" />
<CardNumberInputField inputName="3" />
</div>
);
}
function CardNumberInputField(props) {
return (
<div>
<input id={props.inputName} name={props.inputName} type="text" />
</div>
);
}
// Main render
ReactDOM.render(<CardForm />, document.getElementById("root"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="root"></div>
Related
I added react to an HTML page. With this approach, how can I write a class above my App class and import it to use within Class?
class Header extends React.Component
above my App class but it I keep getting an error:
super expression must be null or a function
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" type="text/css" href="style.css" media="screen" />
</head>
<body>
<div id="root"></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.4.2/react.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.4.2/react-dom.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/babel-standalone/6.21.1/babel.min.js"></script>
<script src="https://code.jquery.com/jquery-3.3.1.min.js" integrity="sha256-FgpCb/KJQlLNfOu91ta32o/NMZxltwRo8QtmkMRdAu8=" crossorigin="anonymous"></script>
<script type="text/babel">
class App extends React.Component {
componentDidMount() {}
render() {
return (
<div className="">
</div>
);
}
}
ReactDOM.render(
<App/>,
document.getElementById('root')
);
</script>
</body>
</html>
The class would be just another React Component, so you can just render it as you would any:
class Header extends React.Component {
render() {
return (
<h1>My Custom Header</h1>
)
}
}
class App extends React.Component {
componentDidMount() {
}
render() {
return (
<div className="">
<Header/>
</div>
);
}
}
ReactDOM.render(
<App />,
document.getElementById('root')
);
That said, you might just want to use functional components in such (stateless) cases.
I have this simple app, where I'm looking for a solution to connect the click from the text to the image. Here, the click is not toggeable, just click once and the image is supposed to appear. First, I thought that would make sense to define a state for the image, but honestly I don't think is the best practice.
Which is the best solution for this kind of situation? I aprecciate any provided tips and solutions.
Thank you.
// IMAGE COMPONENT
class Image extends React.Component {
render() {
return (
<div>
<img
alt=""
src="https://media.makeameme.org/created/what-if-I-y0ivox.jpg"
/>
</div>
);
}
}
// TEXT COMPONENT
class Text extends React.Component {
imageClick() {
console.log('click');
}
render() {
return (
<div>
<p onClick={this.imageClick}>If you click me, Morpheus will appear!</p>
</div>
)
}
}
// PARENT COMPONENT
class App extends React.Component {
render () {
return (
<div>
<Text onClick={this.imageClick} />
<Image src={this.props.src} />
</div>
);
}
}
ReactDOM.render(<App />, document.getElementById("app"));
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<meta name="theme-color" content="#000000">
<link rel="manifest" href="%PUBLIC_URL%/manifest.json">
<link rel="shortcut icon" href="%PUBLIC_URL%/favicon.ico">
<title>React App</title>
</head>
<body>
<div id="app"></div>
</body>
</html>
Use the parent component to set the visibility of the image.
// IMAGE COMPONENT
class Image extends React.Component {
render() {
return (
<div>
<img
alt=""
src="https://media.makeameme.org/created/what-if-I-y0ivox.jpg"
/>
</div>
);
}
}
// TEXT COMPONENT
class Text extends React.Component {
render() {
return (
<div>
<p onClick={() => this.props.onClick()}>If you click me, Morpheus will appear!</p>
</div>
)
}
}
// PARENT COMPONENT
class App extends React.Component {
state = {
visible : false,
}
toggleVisible = () => this.setState({ visible : !this.state.visible });
render () {
const { visible } = this.state;
return (
<div>
<Text onClick={this.toggleVisible} />
{
visible
&& <Image src={this.props.src} />
}
</div>
);
}
}
ReactDOM.render(<App />, document.getElementById("#app"));
<div>
Player One <input ref="p1Name"/>
Player Two <input ref="p2Name"/>
<button onClick={() => this.submit(this.refs.p1Name.value, this.refs.p2Name.value)}>submit result</button>
</div>
This code submits as expected. but i want to submit it as on object. i have tried wrapping the arguments in {} but it then complains about the this keyword. how can i submit it so the function receives it as an object?
This is what I have tried:
<button onClick={() => this.submit({this.refs.p1Name.value, this.refs.p2Name.value})}>submit result</button>
You can wrap them in an object like this:
this.submit({a: this.refs.p1Name.value, b: this.refs.p2Name.value})}
A working example:
class App extends React.Component {
constructor(props) {
super(props);
this.submit = this.submit.bind(this);
}
submit(params) {
console.log(params);
}
render() {
return (
<div>
Player One <input ref="p1Name" />
Player Two <input ref="p2Name" />
<button
onClick={() =>
this.submit({a: this.refs.p1Name.value, b: this.refs.p2Name.value})}
>
submit result
</button>
</div>
);
}
}
ReactDOM.render(<App />, document.getElementById("root"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="root"></div>
I have to make a card.
For that I need to make 3 components.
First for Card Header
Second for Card Description and
Third for main Card that will give values to both components.
In my Card class I want to display the array data. I have no idea how to do that.
I believe I should use map() but I do not understand how.
My structure should be like Card header1 with Card description1 then Card header2 with Card description2.
<!Doctype html>
<html>
<head>
<title>React Cards</title>
<link rel="stylesheet" href="screen1.css" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.0.2/react.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.0.2/react-dom.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/0.13.3/JSXTransformer.js"></script>
</head>
<body>
<script type="text/jsx">
class Header extends React.Component { render () { return (
<div className='t1'>
<h1>{this.props.text}</h1>
</div>
) } } class CardDesc extends React.Component { render () { return (
<div className='t2' id='this.props.id'>{this.props.text}</div>
) } } class Card extends React.Component { render () { return (
<div className='t3'>
<Header text="this.props.head" />
<CardDesc text="this.props.des" />
</div>
) } } var cardContent = [ {head:'Header one',des:'000'}, {head:'Header two',des:'001'},
{head:'Header three',des:'002'}, {head:'Header four',des:'004'}, {head:'Header
five',des:'005'}, {head:'Header six',des:'006'} ]; ReactDOM.render(
<Card />, document.getElementById('root'))
</script>
<div id="root"></div>
</body>
</html>
When you want to pass a variable as props, don't use quotes, instead use {}, so change:
<Header text="this.props.head"/>
<CardDesc text="this.props.des" />
To:
<Header text={this.props.head}/>
<CardDesc text={this.props.des} />
Now, you can simply render your cards like so:
ReactDOM.render(
<div>
{cardContent.map(cardItem => <Card head={cardItem.head} des={cardItem.des} />)}
</div>
, document.getElementById('root'))
As you can see, a root element (div in this case) is required for the render function.
Another method would be to create a CardList component, and render that, instead of having the map in ReactDOM.render.
I think multiple rendering to the root element is bad idea, you can try create new component like App or whatever, end map your card components into it.
Look at this
I have a parent component, which is basically a Form.
export default class Parent extends Component{
submitInput(event){
...call Children
}
render(){
return(
<div>
<form className="form-horizontal" onSubmit= {this.submitInput.bind(this)}>
{this.props.children}
<button type="submit">Submit</button>
</div>
</form>
</div>);
}}
The children can be different types of inputs all with a common function called validate().
Here is one example of a child
export default class Child extends Component{
validate(){
..validate stuff
}
render(){
return(
<div className="form-group">
<textarea ref={this.props.name} />
</div>
);
}
}
On Submission of the parent Component I want validate all Child inputs using their validate() function.
How can I do that?
Thanks in advance
Clone the entire children with new ref prop using React.cloneElement. On submit use the refs to access the child's methods.
See the example below. If more elaboration needed, please comment.
Hope this helps!
class Form extends React.Component{
submitInput(){
this.childrenClone.forEach((el) => {
var r = el.ref //use the ref to access the child's methods
this.refs[r].validate()
})
}
render() {
this.childrenClone = React.Children.map(this.props.children,
(child) => React.cloneElement(child, {
ref: Math.random().toString(36).slice(-5) //add a random string as a ref
})
)
return <div>
<form className="form-horizontal" onSubmit={this.submitInput.bind(this)}>
{this.childrenClone}
<button type="submit">Submit</button>
</form>
</div>
}
}
class Child extends React.Component{
validate(){
console.log('validate textarea') //on validate log this
}
render() {
return <div className="form-group">
<textarea />
</div>
}
}
class ChildInput extends React.Component{
validate(){
console.log('validate Input') //on validate log this
}
render() {
return <div className="form-group">
<input type="text" />
</div>
}
}
class Parent extends React.Component{
render(){
return <Form>
<Child/>
<Child/>
<ChildInput/>
<ChildInput/>
</Form>
}
}
ReactDOM.render(<Parent/>, document.getElementById('app'))
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="app"></div>