How can I extract the innerHTML from the onBlur event?
I have previously only used onChange and onClick event handlers. In those cases the event argument (or at least first argument) passed to the callback has been an object from which I have been able to extract event.target.value.
But the onBlur event returns another kind of object:
Proxy {[[Handler]], [[Target]], [[IsRevoked]]}
How do I extract innerHTML from that?
import React, { Component } from "react";
export default class Subject extends Component {
constructor(props) {
super(props);
}
onBlur(event) {
console.log(event);
}
render() {
return (
<div>
<p>subject</p>
<p contenteditable="true" name='subject' onBlur={this.onBlur}>{this.props.subject}</p>
</div>
)
}
}
To get data from contentEditable you can do console.log(event.target.textContent).
So your program will look like
import React, { Component } from "react";
export default class Subject extends Component {
constructor(props) {
super(props);
}
onBlur(event) {
console.log(event.target.textContent);
}
render() {
return (
<div>
<p>subject</p>
<p contentEditable="true" name='subject' onBlur={this.onBlur}>{this.props.subject}</p>
</div>
)
}
}
Related
I wanted to pass image link through 2 child components. I put my link inside state and passed it but it's not working. When I manually put link in child component it's working the way it should. What is the matter, can't figure it out.
class App extends React.Component{
state = {
currentImage: 'http://steemitimages.com/640x0/https://steemitimages.com/DQmZ5ZTZGH7odGrk3N7m6xvn2tS4Uz5G2RtkN5A2mM1GZnk/Lucius-Seneca-451x500.png',
}
render(){
return (
<>
<Window
image={this.state.currentImage}
/>
<Form/>
</>
);
}
}
//First Child
class Window extends React.Component {
render() {
return (
<div className={styles.wrapper}>
<div className={styles.content}>
<Quote image={this.props.image}/>
</div>
</div>
)
}
}
//Target child that should display pic
class Quote extends React.Component {
render() {
return(
<div className={styles.wrapper}>
<img
src={this.props.image}
className={styles.image}
/>
</div>
)
}
}
I think you should make a constructor.
class App extends React.Component{
constructor(props) {
super(props);
this.state = {
currentImage: 'https://steemitimages.com/DQmZ5ZTZGH7odGrk3N7m6xvn2tS4Uz5G2RtkN5A2mM1GZnk/Lucius-Seneca-451x500.png'
};
}
render(){
return (
<>
<Window
image={this.state.currentImage}
/>
<Form/>
</>
);
}
}
There is no problem with props.. Just you misused state in App component.
I need to get a width of html element, using React JS. When I do console.log(this.widthPromoLine) in componentDidMount(), it works, but when I do this.setState({moveContent: this.widthPromoLine}), it doesn't.
import React from 'react'
import './index.css'
class Promo extends React.Component {
constructor(props){
super(props)
this.state = {
moveContent: 0
}
}
componentDidMount(){
this.setState({moveContent: this.widthPromoLine})
}
render(){
return <div
className="promo-content"
ref={promoLine => this.widthPromoLine = promoLine.clientWidth}>
</div>
}
}
.promo-content {
width: 1870px;
}
Access the clientWidth after the ref has been assigned to the variable this.widthPromoLine in componentDidMount and then set it like below. Also setState is async, so you need to do anything after the state has been updated in the callback of setState.
import React from "react";
import "./styles.css";
class Promo extends React.Component {
constructor(props) {
super(props);
this.state = {
moveContent: 0
};
}
componentDidMount() {
this.setState({ moveContent: this.widthPromoLine.clientWidth }, () => {
console.log(this.state);
});
}
render() {
return (
<div
className="promo-content"
ref={promoLine => (this.widthPromoLine = promoLine)}
/>
);
}
}
Hope this helps !
You can get the width of content using it classname as follow.
let width = document.querySelector(".promo-content").offsetWidth;
And after that update the state,
this.setState({moveContent: width})
First thing I learnt about mobx-react is use "#observer" attribute to track values of properties which defined in state class..
this is my sample below;
//#observer cut it off
SingUp.js
import React, {Component} from 'react'
import {observer} from 'mobx-react'
class SignUp extends Component{
constructor(props){
super(props)
}
SaveUser(e){
e.preventDefault();
this.props.appState.user.username = this.username.value;
this.props.appState.user.password = this.password.value;
this.props.appState.postSaveUser();
}
render(){<form onSubmit={()=>this.SaveUser(e)}>...
when I submit the form it "SaveUser()" called and set app state values. you see I dont define "#observer" attribute at top of SignUp class
and here is state class; AppState.js
import { observable, action} from "mobx"
import {user} from './models/user'
class AppState {
#observable user=new user;
constructor() {
}
postSaveUser(){
debugger
var asd = this.user
}
}
the thing is when I check the values in "postSaveUser()" method I see values exactly I set it "SignIn" component, is it weird?
I thought it only track values assigned in any class which defined with "#observer" attribute but although I dont use it I am able to access data?
Using the #observer decorator on a React component class is much like using autorun. The component will re-render when the observables that got de-referenced in the last render are changed. You can still of course change the value of observable data, it is just that your React component will not re-render automatically if you don't use the #observer decorator.
Example (JSBin)
class Store {
#observable data = 'cool';
}
const store = new Store();
setTimeout(() => {
store.data = 'wow';
}, 2000);
#observer
class Observer extends Component {
render() {
return <h1> This component will re-render when {store.data} changes.</h1>;
}
};
class NonObserver extends Component {
render() {
return <h1> This component will NOT re-render when {store.data} changes.</h1>;
}
};
ReactDOM.render(
<div>
<Observer />
<NonObserver />
</div>,
document.getElementById('app')
);
I have created a overlay element and I want it to appear when a certain input field is clicked. I'm new to react so it's not clear to me how I should do it.
This is the view that should appear
import React, { Component } from 'react';
import pro_pic from '../../Resources/img/Anon.jpg';
import menu_drop from '../../Resources/img/drop.png';
class QuestionOverlay extends Component {
render() {
return (
<div id="overlay">
</div>
)
}
}
export default QuestionOverlay;
The click event is here
render() {
function popup_ques(e) {
e.preventDefault();
alert("render overlay view");
}
return (
<div className="middle_div">
<input className='post_data_input' placeholder="Ask your question here" ref="postTxt"
onClick={popup_ques}/>
</div>
);
}
So when I click the input field, the overlay I have created should appear instead of the alert I have given.
This is what I would do:
constructor(props) {
super(props);
this.state = {
overlayVisible: false
}
}
render() {
function popup_ques(e) {
e.preventDefault();
this.setState({
overlayVisible: true
});
}
return (
<div className="middle_div">
<input
className='post_data_input'
placeholder="Ask your question here"
ref="postTxt"
onClick={popup_ques}/>
{this.state.overlayVisible && <QuestionOverlay />}
</div>
);
}
Your function has to be pure, so, based on a state you get an UI render, if you want to insert something, you change your state, but your render function remains the same.
However that approach effectively constructs a new overlay every time you show it, if you want to keep the state perhaps it is better to keep the component but change it's rendering:
import React, { Component } from 'react';
class QuestionOverlay extends Component {
render() {
if(!this.props.visible) {
return null
}
return (<div id="overlay"/>)
}
}
export default QuestionOverlay;
And the container:
constructor(props) {
super(props);
this.state = {
overlayVisible: false
}
}
render() {
function popup_ques(e) {
e.preventDefault();
this.setState({
overlayVisible: true
});
}
return (
<div className="middle_div">
<input
className='post_data_input'
placeholder="Ask your question here"
ref="postTxt"
onClick={popup_ques}/>
<QuestionOverlay visible={this.state.overlayVisible}/>
</div>
);
}
import React from 'react';
import { Router, Link, Navigation } from 'react-router';
export default class ResourceCard extends React.Component {
render() {
return (
<div onClick={this.routeHandler.bind(this)}>
LINK
</div>
);
}
routeHandler(){
this.transitionTo('someRoute', {objectId: 'asdf'})
}
}
I can't get it, what's wrong?
I'm receiving an error:
Uncaught TypeError: this.transitionTo is not a function
I've tried everything I've find in docs or in gitHub issues:
this.transitionTo('someRoute', {objectId: 'asdf'})
this.context.transitionTo('someRoute', {objectId: 'asdf'})
this.context.route.transitionTo('someRoute', {objectId: 'asdf'})
etc.
the route and the param is correct, it works fine in this case:
<Link to="'someRoute" params={{objectId: 'asdf}}
p.s. react-router, react and other libraries is up to date
The Navigation component is a Mixin and needs to be added to the component accordingly. If you want to bypass the Mixin (which I feel is the direction React-Router is going) you need to set the contextTypes on the component like so:
var ResourceCard = React.createClass({
contextTypes: {
router: React.PropTypes.func
}, ...
then you can call this.context.router.transitionTo.
This works with react 0.14.2 and react-router 1.0.3
import React from 'react';
import { Router, Link } from 'react-router';
export default class ResourceCard extends React.Component {
constructor(props,) {
super(props);
}
render() {
return (
<div onClick={this.routeHandler.bind(this)}>
LINK
</div>
);
}
routeHandler(){
this.props.history.pushState(null, '/');
}
}
As there's no mixin support for ES6 as of now , you need to change a few things to make it work .router is an opt-in context type so you will have to explicitly define contextTypes of the class . Then in your constructor You will have to pass context and props to super class. And while calling transitionTo you'll have to use this.context.router.transitionTo . and you don't need to import Navigation.
import React from 'react';
import { Router, Link } from 'react-router';
export default class ResourceCard extends React.Component {
constructor(props, context) {
super(props, context);
}
render() {
return (
<div onClick={this.routeHandler.bind(this)}>
LINK
</div>
);
}
routeHandler(){
this.context.router.transitionTo('someRoute', {objectId: 'asdf'})
}
}
ResourceCard.contextTypes = {
router: function contextType() {
return React.PropTypes.func.isRequired;
}
};