I need create a custom input fot imagem , but don`t send value for my api
When I try create custom input, it show and work but don`t send a value
import React from 'react';
class InputImage extends React.Component{
constructor(props) {
super(props);
this.state = {
src: ''
};
this._handleImageChange = this._handleImageChange.bind(this);
}
_handleImageChange = (e) => {
const file = e.target.files[0];
let reader = new FileReader();
reader.onloadend = () => {
this.setState({src:reader.result})
};
reader.readAsDataURL(file);
}
render(){
return (
<>
<input source={this.props.source} type="hidden" value={this.state.src} />
<input type="file" onChange={this._handleImageChange} />
</>
)
}
}
export default InputImage;
Related
const displayNameRef = useRef('');
useEffect(() => {
(async () => {
const loginMethod = await AsyncStorage.getItem('login-method');
if (loginMethod === 'google') {
displayNameRef.current = await AsyncStorage.getItem('google-user-name');
setState((s) => s + 1);
} else {
displayNameRef.current = 'Randomly_generated';
}
})();
}, []);
this is my useffect, here i getitem(display name )from async storage but i want to convert all the hooks into class component
<Header
title={('hi', displayNameRef.current)}
setSelectedTab={this.setSelectedTab}
selectedTab={this.state.selectedTab}
navigation={this.props.navigation}
openDrawerPanel={this.openDrawerPanel}
/>
so here i want to display displayNameRef.current inside of header
If you want to turn your hooks into class component, try to process à below:
class SomeCalss extends React.Component {
constructor(props) {
super(props);
this.state = {
s: 0
}
this.displayNameRef = React.createRef();
}
async componentDidMount() {
const loginMethod = await AsyncStorage.getItem('login-method');
if (loginMethod === 'google') {
displayNameRef.current = await AsyncStorage.getItem('google-user-name');
this.setState({s: this.state.s + 1});
} else {
displayNameRef.current = 'Randomly_generated';
}
}
render() {
return <Header
title={('hi', this.displayNameRef.current)}
setSelectedTab={this.setSelectedTab}
selectedTab={this.state.selectedTab}
navigation={this.props.navigation}
openDrawerPanel={this.openDrawerPanel}
/>
}
}
But you have to be aware that displayNameRef.current = 'Randomly_generated'; doesn't trigger re-render
Nextjs Firebase Phone Auth
First attempt useEffect()
useEffect(() => {
window.recaptchaVerifier = new firebase.auth.RecaptchaVerifier('recaptcha', {
'size': 'invisible',
'callback': (response) => {
console.log("This is not fired on loading", response)
}
})
}, [])
return (
<>
<div id="recaptcha"></div>
<button onClick={clicked}> Click me </button>
</>
)
This runs, however the recaptcha doesn't work... User is forced to pick fire hydrants.
Second attempt: React Component
Inspiration: https://stackoverflow.com/a/63860925/7451631
Import this to Login page
class Recap extends Component {
constructor(props) {
super(props);
this.signIn = this.signIn.bind(this);
}
componentDidMount() {
window.reCaptchaVerifier = new firebase.auth.RecaptchaVerifier(this.recaptcha, {
'size': 'invisible',
'callback': function (response) {
console.log("Magic", response)
}
})
}
signIn() {
firebase.auth().signInWithPhoneNumber(phoneNumber, window.reCaptchaVerifier).catch((error) => {
console.log(error)
})
}
render() {
return (
<>
<div ref={(ref) => this.recaptcha = ref} onClick={this.signIn}> Clik meeeee </div>
</>
)
}
}
Works! I got a ugly solution while typing up this question. If anyone knows how to make it nicer or can explain why the first attempt did not work that would be dope.
here is my solutions:
import { createFirebaseApp } from '#utils/firebase';
import { getAuth, PhoneAuthProvider, RecaptchaVerifier, signInWithCredential } from 'firebase/auth';
import { useState } from 'react';
export default function Example() {
const app = createFirebaseApp();
const auth = getAuth(app);
const [code, setCode] = useState('');
const [verificationId, setVerificationId] = useState('');
const signInWithPhone1 = async () => {
const applicationVerifier = new RecaptchaVerifier(
'sign-in-button',
{
size: 'invisible',
},
auth,
);
const provider = new PhoneAuthProvider(auth);
const vId = await provider.verifyPhoneNumber('+855012000001', applicationVerifier);
setVerificationId(vId);
};
const verify = async () => {
const authCredential = PhoneAuthProvider.credential(verificationId, code);
const userCredential = await signInWithCredential(auth, authCredential);
console.log('verify: ', userCredential);
};
return (
<>
<button id="sign-in-button" onClick={signInWithPhone1}>
SignIn With Phone1
</button>
<div>
<input type="text" value={code} onChange={(v) => setCode(v.target.value)} />
<button onClick={verify}>Verify</button>
</div>
</>
);
}
I have a box containing a list. The list is made of todoItems. A delete button is next to each item. The button should call the delete method of the box class. Should I pass it to the class List first? Can I call directly the method in the class Box?
class TodoItem extends React.Component {
constructor(props) {
super(props);
this.handleClick = this.handleClick.bind(this);
}
handleClick(e)
{
const todoItemId = this.props.todoItemId;
if (!todoItemId)
{
return;
}
this.props.onTodoItemDeleteList({ todoItemId: todoItemId });
}
render() {
return (
<div className="todoItem">
<button onClick={() => this.handleClick()}>delete</button>;
</div>
);
}
}
My List: here the onTodoItemDeleteList is seen in the console, but appears as undefined.
class TodoItemList extends React.Component {
constructor(props) {
super(props);
this.handleItemDeleteList = this.handleItemDeleteList.bind(this);
}
handleItemDeleteList(todoItemId)
{
//call handleItemDelete
}
render() {
if (this.props.data)
{
var todoItemNodes = this.props.data.map(function (todoItem){
return (
<TodoItem todoItemId={todoItem.todoItemId} onTodoItemDeleteList={this.handleItemDeleteList} key={todoItem.todoItemId}>
</TodoItem>
);
});
}
return <div className="todoItemList">{todoItemNodes}</div>;
}
}
My Box: this is where I handle my ajax call to the server.
class TodoItemBox extends React.Component {
constructor(props) {
super(props);
this.state = { data: [] };
this.handleItemDelete = this.handleItemDelete.bind(this);
}
handleItemDelete(todoItemId) {
const data = new FormData();
data.append('todoItemId', todoItemId);
const xhr = new XMLHttpRequest();
xhr.open('post', this.props.deleteUrl, true);
xhr.onload = () => this.loadTodoItemsFromServer();
xhr.send(data);
}
render() {
return (
<div className="todoItemBox">
<TodoItemList data={this.state.data} />
</div>
);
}
}
I solved it by using arrow function in the parent too, it looks like this:
onTodoItemDeleteList={ (todoItemId) => handleItemDeleteList(todoItemId)}
and in the constructor:
handleItemDeleteList = this.handleItemDeleteList.bind(this);
I just started learning react-native and I have a problem with my input fields.
I do not have any compilation errors but when I execute and I press the button I have an error:
Undefined is not an object ('this.state.username')
This is probably linked to poor state management.
Here is my code:
import React, { Component } from 'react';
import {
Platform,
StyleSheet,
Text,
View,
TextInput,
Button
} from 'react-native';
export default class App extends Component<Props> {
constructor(props) {
super(props);
this.state = {
username: '',
password: ''
};
};
_userSignup() {
const username = this.state.username;
const password = this.state.password;
}
render() {
return (
<TextInput
onChangeText={(text) => this.setState({username:text})}
value={this.state.username}
placeholder = "Username"
/>
<TextInput
onChangeText={(password) => this.setState({password})}
value={this.state.password}
placeholder = "Password"
/>
<Button
title="sign in"
onPress={this._userSignup}
/>
</View>
);
}
}
Thank you for your help.
You either do this
_userSignup() {
const { username } = this.state;
const { password } = this.state;
}
or do this
_userSignup() {
const username = this.state.username;
const password = this.state.password;
}
Learn more about ES6 destructuring feature or check out what Dan has to say about it.
I have created two components LoginView and Login Form. LoginView uses LoginForm component for rendering. I am writing test cases for LoginView and LoginForm separately. The issue is when I import the LoginView and LoginForm component in a single spec, it works fine. But as I am trying to import same either components it raises an error
Invariant Violation: addComponentAsRefTo(...): Only a ReactOwner can have refs. You might be adding a ref to a component that was not created inside a component's render method, or you have multiple copies of React loaded.
The error says that
I might be using multiple copies of React, but I am using
react#15.3.2 and material-ui#0.15.4
The use of 'ref', I have not used 'ref' but Material-ui uses ref for
their component.
I am unable to solve issue, any help/ suggestions are appreciated.
Node v6.6.0
NPM 3.10.3
Files are:
LoginView:
import React from 'react';
import { FlatButton, Dialog } from 'material-ui';
import BaseComponent from './BaseComponent';
import LoginForm from './LoginForm';
export default class LoginView extends BaseComponent {
// statements
render(
<LoginForm onSubmit={this.handleSubmit} loading={loading} />
<br />
<FlatButton
secondary
onClick = { this.navToRegister }
label = {__('No Account? Create one.')}
/>
<br />
<FlatButton
secondary
onClick = { this.navToForgotPassword }
label = {__('Forgot your password?')}
/>
<br />
)
}
LoginForm:
import React from 'react';
import { TextField, RaisedButton } from 'material-ui';
export default class LoginForm extends React.Component {
// Statements
return (
<form onSubmit={this.handleSubmit}>
<TextField
type = "text"
/>
<br />
<TextField
type= "password"
/>
<br />
<RaisedButton
type = "submit"
/>
</form>
);
}
Spec Files:
Login Form:
import React from 'react';
import { mount } from 'enzyme';
import getMuiTheme from 'material-ui/styles/getMuiTheme';
import LoginForm from '../../src/components/LoginForm';
import baseTheme from '../../src/style/muiThemes/neo';
describe('Login ', () => {
describe('LoginForm test case ', () => {
const context = { muiTheme: getMuiTheme(baseTheme) };
const email = 'test#mail.com';
const pass = 'testPassword';
let form = null;
let textField = null;
let emailInput = null;
let passwordInput = null;
let submitButton = null;
let submitSpy = null;
let wrapper = null;
beforeEach(() => {
submitSpy = chai.spy.on(LoginForm.prototype, 'handleSubmit');
wrapper = mount(<LoginForm onSubmit={submitSpy} />, { context });
form = wrapper.find('LoginForm');
textField = wrapper.find('TextField');
emailInput = textField.get(0);
passwordInput = textField.get(1);
submitButton = wrapper.find('button[type="submit"]');
});
// Some test scenarios
}
Login View:
import React from 'react';
import { mount } from 'enzyme';
import getMuiTheme from 'material-ui/styles/getMuiTheme';
import LoginView from '../../src/components/LoginView'; // Error while importing this file.
import baseTheme from '../../src/style/muiThemes/neo';
describe('LoginView test cases', () => {
const context = { muiTheme: getMuiTheme(baseTheme) };
let submitSpy = null;
let wrapper = null;
let loginForm = null;
beforeEach(() => {
submitSpy = chai.spy.on(LoginView.prototype, 'handleSubmit');
wrapper = mount(<LoginView onSubmit={submitSpy} />, { context });
loginForm = wrapper.find('LoginForm');
});
it('calls componentDidMount', () => {
const spy = chai.spy.on(LoginView.prototype, 'componentDidMount');
wrapper = mount(<LoginView />, { context });
expect(spy).to.have.been.called.once;
});
it('Access the dom', () => {
expect(loginForm).not.to.equal(undefined);
});
});