如何将数据从一个[HttpPost]
public ActionResult Insert(<SomeOtherModel> otherModel, IEnumberable<Test> model){
foreach (var item in model){
//to do here
}
}
表单( component )传递到另一个组件。例如,如果我需要玩家React hooks
从name and photo
传球并使其在Profile.js
中可用,我该怎么做?
Navigation.js
Player.js
import React, { useContext , useEffect, useState } from "react";
import { useForm } from 'react-hook-form';
import { useHistory } from "react-router-dom";
import Axios from "axios";
import UserProfileContext from '../context';
const Profile = () => {
const { setData } = useContext(UserProfileContext);
const [email, setEmail] = useState('');
const [picture, setPicture] = useState('');
const [playerProfile, setPlayerProfile] = useState([]);
const loginUserEmail = localStorage.getItem('loginEmail');
const [updateProfile, setUpdateProfile] = useState({ _id: '', photo: '', name: '', email:'', phonenumber: '', position: '', password: '' })
const [isSent, setIsSent] = useState(false);
const [helperText, setHelperText] = useState('');
const [disabled, setDisabled] = useState(true);
const { handleSubmit, register, errors } = useForm();
const history = useHistory();
const onChangePicture = e => {
console.log('picture: ', picture);
if (e.target.files.length) {
setPicture(URL.createObjectURL(e.target.files[0]));
} else {
return false;
}
};
// If no profile image is being uploaded, to avoid the broken display of image, display a default image.
const addDefaultSrc = e => {
e.target.src = '/images/default-icon.png';
}
// Pass the id to the handler so you will know which item id changing.
const handleChange = (e, id) => {
e.persist();
let itemIndex;
const targetPlayer = playerProfile.find((player, index) => {
console.log({ player, id, index });
itemIndex = index; // Track the index so you can use it to update later.
return player.id === id;
});
console.log({ targetPlayer, id, e });
const editedTarget = {
...targetPlayer,
[e.target.name]: e.target.value
};
const tempPlayers = Array.from(playerProfile);
tempPlayers[itemIndex] = editedTarget;
/*
// Alternatively:: you can just map over the array if you dont want to track the index
const tempPlayers = playerProfile.map((profile, index) => {
return profile.id === id ? editedTarget : profile;
});
*/
setPlayerProfile(tempPlayers);
setUpdateProfile({ ...updateProfile, [e.target.name]: e.target.value }); // this is added just to see if its working
};
useEffect(() => {
const fetchData = async () => {
try {
const params = {
email: loginUserEmail,
};
const res = await Axios.get('http://localhost:8000/service/profile', {params});
setPlayerProfile(res.data.playerProfile);
} catch (e) {
console.log(e);
}
}
fetchData();
}, []);
const onSubmit = () => {
setDisabled(disabled);
const fetchData = async () => {
try {
const params = {
email: loginUserEmail,
};
const data = {photo: updateProfile.photo, name: updateProfile.name, email: updateProfile.email, phonenumber: updateProfile.phonenumber, position: updateProfile.position, password: updateProfile.password}
const res = await Axios.put('http://localhost:8000/service/profile', data, {params});
console.log("Front End update message:" + res.data.success);
if (res.data.success) {
setIsSent(true);
history.push('/')
}
else {
console.log(res.data.message);
setHelperText(res.data.message);
}
} catch (e) {
setHelperText(e.response.data.message);
}
}
fetchData();
}
return (
<div className="register_wrapper">
<div className="register_player_column_layout_one">
<div className="register_player_Twocolumn_layout_two">
<form onSubmit={handleSubmit(onSubmit)} className="myForm">
{
playerProfile.map(({ id, photo, name, email, phonenumber, position, privilege, password }) => (
<div key={id}>
<div className="formInstructionsDiv formElement">
<h2 className="formTitle">Profile</h2>
<div className="register_profile_image">
<input id="profilePic" name="photo" type="file" onChange={onChangePicture} />
</div>
<div className="previewProfilePic" >
<img alt="" onError={addDefaultSrc} name="previewImage" className="playerProfilePic_home_tile" src={photo} onChange={e => handleChange(e, id)}></img>
</div>
</div>
<div className="fillContentDiv formElement">
<label>
<input className="inputRequest formContentElement" name="name" type="text" value={name}
onChange={e => handleChange(e, id)}
maxLength={30}
ref={register({
required: "Full name is required",
pattern: {
value: /^[a-zA-Z\s]{3,30}$/,
message: "Full name should have minimum of 3 letters"
}
})}
/>
<span className="registerErrorTextFormat">{errors.name && errors.name.message}</span>
</label>
<label>
<input className="inputRequest formContentElement" name="email" type="text" value={email}
onChange={e => handleChange(e, id)}
disabled={disabled}
/>
</label>
<label>
<input className="inputRequest formContentElement" name="phonenumber" type="text" value={phonenumber}
onChange={e => handleChange(e, id)}
maxLength={11}
ref={register({
required: "Phone number is required",
pattern: {
value: /^[0-9\b]+$/,
message: "Invalid phone number"
}
})}
/>
<span className="registerErrorTextFormat">{errors.phonenumber && errors.phonenumber.message}</span>
</label>
<label>
<input className="inputRequest formContentElement" name="position" type="text" value={position}
onChange={e => handleChange(e, id)}
maxLength={30}
ref={register({
pattern: {
value: /^[a-zA-Z\s]{2,30}$/,
message: "Position should have minimum of 2 letters"
}
})}
/>
<span className="registerErrorTextFormat">{errors.position && errors.position.message}</span>
</label>
<label>
<div className="select" >
<select name="privilege" id="select" value={privilege} onChange={e => handleChange(e, id)}>
{/*<option selected disabled>Choose an option</option> */}
<option value="player">PLAYER</option>
{/*<option value="admin">ADMIN</option>*/}
</select>
</div>
</label>
<label>
<input className="inputRequest formContentElement" name="password" type="password" value={password}
onChange={e => handleChange(e, id)}
minLength={4}
maxLength={30}
ref={register({
required: "Password is required",
pattern: {
value: /^(?=.*?\d)(?=.*?[a-zA-Z])[a-zA-Z\d]+$/,
message: "Password begin with a letter and includes number !"
}
})}
/>
<span className="registerErrorTextFormat">{errors.password && errors.password.message}</span>
</label>
</div>
<label>
<span className="profileValidationText">{helperText}</span>
</label>
<div className="submitButtonDiv formElement">
<button type="submit" className="submitButton">Save</button>
</div>
</div>
))
}
</form>
</div>
</div>
</div>
);
}
Navigation.js
import React, { useContext } from 'react';
import { NavLink, useHistory } from 'react-router-dom';
import UserProfileContext from '../context';
const Navigation = () => {
const history = useHistory();
const { data } = useContext(UserProfileContext);
const divStyle = {
float:'left',
color: '#64cad8',
padding: '0px 0px 0px 10px',
font:'Lucida, sans-serif'
};
function logout() {
localStorage.removeItem('loginEmail')
localStorage.removeItem('Privilege')
history.push('/login')
window.location.reload(true);
}
return localStorage.getItem('loginEmail') &&
<div className="App">
<div className="wrapper">
<nav className="siteNavigation_nav_links">
<div className="clubLogo landing"style={divStyle}><b>Southside Soccer</b></div>
<NavLink className="mobile_register_link" to="/">Home</NavLink>
<NavLink className="mobile_register_link" to="/profile">Profile</NavLink>
<NavLink className="mobile_login_link" to="/login" onClick={logout}>Logout</NavLink>
<NavLink className="mobile_login_link" to='/aboutus'>About us</NavLink>
<div className="profileImage nav menu">
<span>{data.name}</span>|<img src=""></img>
</div>
</nav>
</div>
</div>
}
export default Navigation;
App.js
import React, { useState } from 'react';
import "./App.css";
import "./CSSModules/home.css";
import "./CSSModules/register.css";
import "./CSSModules/login.css";
import "./CSSModules/aboutus.css";
import { BrowserRouter, Route, Switch } from "react-router-dom";
import Home from "./components/Home";
import Register from "./components/Register";
import Login from "./components/Login";
import Aboutus from "./components/Aboutus";
import Navigation from "./components/Navigation";
import Profile from "./components/Profile";
import { ProtectedRoute } from "./components/protected.route";
import UserProfileContext from './context';
var ReactDOM = require("react-dom");
const App = () => {
const [data, setData] = useState({
id: '',
name: '',
email: '',
photo: '',
});
return (
<UserProfileContext.Provider value={{ data, setData }}>
<BrowserRouter>
<>
<Navigation />
<Switch>
<ProtectedRoute exact path="/" component={Home} />
<ProtectedRoute path="/profile" component={Profile} />
<ProtectedRoute path="/aboutus" component={Aboutus} />
<Route path="/register" component={Register} />
<Route path="/login" component={Login} />
</Switch>
</>
</BrowserRouter>
</UserProfileContext.Provider>
);
};
ReactDOM.render(
React.createElement(App, null),
document.getElementById("root")
);
export default App;
context.js
答案 0 :(得分:1)
使用React的内置上下文API。将应用程序包装在上下文提供程序中,然后可以使用useContext钩子访问状态,在组件之间分派状态更新。
应用程序级别设置-一次
// Define Context
const AppContext = React.createContext()
// Define initial state
const initialState = {}
// Define Reducer
const Reducer = (state, dispatch) => {
switch(action.type) {
case "ACTION_TYPE": return {...state, prop: action.payload}
default: return state
}
}
//Wrap main App in context, pass state from React's useReducer hook
const [state, dispatch] = useReducer(Reducer, initialState)
<AppContext.Provider data={{
state,
dispatch
}}>
<ReactAppMainWrapper />
</AppContext.Provider>
组件级别
const {state, dispatch} = useContext(AppContext);
// to update state call dispatch from anywhere, all components consuming state will be updated
dispatch({
type: "ACTION_TYPE",
payload: "new_value"
})
说明
状态就像商店一样在整个应用程序中都可用。
在任何组件中,导入AppContext并使用React的内置useContext挂钩与组件中的商店进行交互。
可以从上面的上下文提供者中传递的数据对象。
答案 1 :(得分:1)
就像评论中提到的那样,一个选项是left your application's state up(这应该是简单状态的首选选项)。
实际上,它看起来像:
App.js
import React, { useState } from 'react';
import Navigation from './Navigation';
import Profile from './Profile';
function App() {
const [name, setName] = useState('');
return (
<div className="App">
<Navigation name={name} />
<hr />
<Profile name={name} setName={setName} />
</div>
);
}
export default App;
Profile.js:
import React from 'react';
const Profile = ({ name, setName }) => {
return (
<>
<div>Profile: {name}</div>
<input
type="text"
name="name"
value={name}
onChange={e => setName(e.target.value)}
/>
</>
);
};
export default Profile;
Navigation.js:
import React from 'react';
const Navigation = ({ name }) => {
return <div>Navigation: {name}</div>;
};
export default Navigation;
编辑:仔细查看您的代码后,我认为在这种情况下使用上下文API更有意义。
尝试以下操作:
context.js
import React from 'react';
export default React.createContext();
App.js
import React, { useState } from 'react';
import { BrowserRouter, Route, Switch } from 'react-router-dom';
import './styles.css';
import Profile from './components/Profile';
import Navigation from './components/Navigation';
import UserProfileContext from './context';
const App = () => {
const [data, setData] = useState({
id: 'player-1',
name: 'Player One',
age: 25,
photo: 'rose.JPG',
});
return (
<UserProfileContext.Provider value={{ data, setData }}>
<BrowserRouter>
<Navigation />
<Switch>
<Route path="/profile" component={Profile} />
</Switch>
</BrowserRouter>
</UserProfileContext.Provider>
);
};
export default App;
components / Navigation.js
import React, { useContext } from 'react';
import { NavLink } from 'react-router-dom';
import UserProfileContext from '../context';
const Navigation = () => {
const { data } = useContext(UserProfileContext);
const divStyle = {
float: 'left',
color: '#64cad8',
padding: '0px 0px 0px 10px',
font: 'Lucida, sans-serif',
};
return (
<div className="App">
<div className="wrapper">
<nav className="siteNavigation_nav_links">
<div className="clubLogo landing" style={divStyle}>
<b>Soccer</b>
</div>
<NavLink className="mobile_register_link" to="/profile">
Profile
</NavLink>
<div className="profileImage nav menu">
<span>{data.name}</span> | <img alt="" src={data.photo} />
</div>
</nav>
</div>
</div>
);
};
export default Navigation;
components / Profile.js
import React, { useContext } from 'react';
import { useForm } from 'react-hook-form';
import UserProfileContext from '../context';
const Profile = () => {
const { setData } = useContext(UserProfileContext);
const { register, handleSubmit } = useForm();
return (
<div>
<form onSubmit={handleSubmit(setData)}>
<b>Profile</b>
<input name="id" ref={register} />
<input name="name" ref={register} />
<input name="age" ref={register} />
<button type="submit" className="submitButton">
Click
</button>
</form>
</div>
);
};
export default Profile;
答案 2 :(得分:0)
您可以利用react-redux
进行全局状态处理,或将回调函数从Navigation.js
传递到Profile.js
。