示例代码:https://github.com/d6u/example-redux-update-nested-props/blob/master/one-connect/index.js
观看现场演示:http://d6u.github.io/example-redux-update-nested-props/one-connect.html
我有上面的组件,Repo和RepoList.我想更新第一个仓库的标签(第14行).所以我发出了一个UPDATE_TAG动作.在我实施之前shouldComponentUpdate,调度大约需要200毫秒,这是预料之中的,因为我们浪费了很多时间<Repo/>来分析没有改变的东西.
添加后shouldComponentUpdate,调度大约需要30ms.在生产构建React.js之后,更新仅花费大约17ms.这要好得多,但Chrome开发者控制台中的时间线视图仍然表示jank帧(超过16.6ms).
想象一下,如果我们有这样的许多更新,或者<Repo/>比当前更新更复杂,我们将无法维持60fps.
我的问题是,对于嵌套组件的道具的这种小更新,是否有更高效和规范的方式来更新内容?我还可以使用Redux吗?
我通过用tags可观察的内部减速器替换每一个来获得解决方案.就像是
// inside reducer when handling UPDATE_TAG action
// repos[0].tags of state is already replaced with a Rx.BehaviorSubject
get('repos[0].tags', state).onNext([{
id: 213,
text: 'Node.js'
}]);
Run Code Online (Sandbox Code Playgroud)
然后我使用https://github.com/jayphelps/react-observable-subscribe在Repo组件中订阅它们的值.这很有效.即使使用React.js的开发构建,每个调度仅花费5ms.但我觉得这是Redux中的反模式.
我按照Dan Abramov的回答中的建议,将我的状态和更新的连接组件规范化
新的状态形状是:
{
repoIds: ['1', '2', '3', ...],
reposById: {
'1': {...},
'2': {...}
}
}
Run Code Online (Sandbox Code Playgroud)
我加了console.time各地 …
我正在尝试使用API中的数据填充配置文件表单.不幸的是,在这种情况下,redux-form不想与我合作.出于某种原因,无论我做什么,田地都会空着
由于某种原因,设置固定值而不是从reducer传递的值很好.
也许这是因为我在动作创建者中使用redux-promise进行API调用?我怎么能忍受它并摆脱它.这是我的表单组件.
import React, { Component } from 'react';
import { reduxForm, Field } from 'redux-form';
import { connect } from 'react-redux';
import { fetchRoleList, fetchUserData } from '../actions';
class UserEdit extends Component {
componentWillMount() {
this.props.fetchRoleList();
this.props.fetchUserData();
}
handleEditProfileFormSubmit(formProps) {
console.log(formProps);
}
getRoleOptions(selected_id) {
if (!this.props.profile) {
return <option>No data</option>;
}
return this.props.profile.roles.map(role => {
return <option key={role.role_id} value={role.role_id}>{role.name}</option>;
});
}
renderField(props) {
const { input, placeholder, label, value, type, meta: { touched, error } } …Run Code Online (Sandbox Code Playgroud) 一切工作正常,但我有这个警告Expected to return a value at the end of arrow function array-callback-return,我尝试使用forEach,而不是map,但后来<CommentItem />甚至不显示.如何解决?
return this.props.comments.map((comment) => {
if (comment.hasComments === true) {
return (
<div key={comment.id}>
<CommentItem className="MainComment"/>
{this.props.comments.map(commentReply => {
if (commentReply.replyTo === comment.id) {
return (
<CommentItem className="SubComment"/>
) // returnt
} // if-statement
}) // map-function
} // map-function __begin
</div> // comment.id
) // returnRun Code Online (Sandbox Code Playgroud)
嗨,我一直被困在 React Function 中useState。我只是想学习 hooks 和 useState,但我什至费力寻找解决方案也没有任何进展。这是我的完整反应功能:
import React, { useState } from 'react';
import './MainPart.css';
function MainPart(props) {
const [orderData_, setOrderData_] = useState(props.orderData);
let topicData_ = props.topicData;
let titleData_ = props.titleData;
let infoData_ = props.infoData;
return (
<div className='MainPart'>
<div className='mainWindow'>{getPics(orderData_)}</div>
<div className='information'>
<div className='moreNewsDivs'>
<div className='moreNewsDiv1'>
<h4>MORE NEWS</h4>
</div>
<div className='moreNewsDiv2'>
<button
className='previous-round'
onClick={setOrderData_(previous(orderData_))}
>
‹
</button>
<button href='/#' className='next-round'>
›
</button>
</div>
</div>
<hr />
<div className='topicDiv'>
<h5 className='topicData'>{topicData_}</h5>
<h5 className='titleData'>{titleData_}</h5>
<h6 className='infoData'>{infoData_}</h6> …Run Code Online (Sandbox Code Playgroud) 商店.ts
export const store = configureStore({
reducer: {
auth: authReducer
},
middleware: [],
});
export type AppDispatch = typeof store.dispatch;
export type RootState = ReturnType<typeof store.getState>;
Run Code Online (Sandbox Code Playgroud)
钩子.ts
export const useAppDispatch = () => useDispatch<AppDispatch>();
export const useAppSelector: TypedUseSelectorHook<RootState> = useSelector;
Run Code Online (Sandbox Code Playgroud)
authSlice.ts(导致问题的函数)
export const fetchUser = createAsyncThunk(
'users/fetchByTok',
async () => {
const res = await getUser();
return res.data;
}
)
Run Code Online (Sandbox Code Playgroud)
授权ts
const Auth = ({ component, isLogged }: {component: any, isLogged: boolean}) => {
const dispatch = useAppDispatch();
useEffect(() => …Run Code Online (Sandbox Code Playgroud) 错误:组件在响应同步输入时挂起。这将导致 UI 被替换为加载指示器。要修复此问题,应使用 startTransition 包装挂起的更新。
当我从组件 B 导航到 A 时,我想保留组件 A 的先前状态。在 React v17 和 React Router v5 中,我能够实现先前的状态。但是使用 React v18,我收到了上述错误。任何想法?
A组份:
const ComponentA = React.lazy(() => import('./ComponentA'));
const App = () => (
<Suspense fallback={<Loader/>}>
<Provider store={store}>
<ComponentA/>
</Provider>
</Suspense>
)
Run Code Online (Sandbox Code Playgroud)
组分B:
const ComponentB = React.lazy(() => import('./ComponentB'));
const App = () => (
<Suspense fallback={<Loader/>}>
<Provider store={store}>
<ComponentB/>
</Provider>
</Suspense>
)
Run Code Online (Sandbox Code Playgroud)
节点:v16.14.2 React:v18 React 路由器:v6
Redux v8 不支持 React v18 https://github.com/reduxjs/react-redux/issues/1740
我使用redux编写了一个容器组件,我对mapDispathToProps的实现看起来像这样
const mapDispatchToProps = (dispatch, ownProps) => {
return {
onChange: (newValue) => {
dispatch(updateAttributeSelection('genre', newValue));
dispatch(getTableData(newValue, ownProps.currentYear));
}
}
}
Run Code Online (Sandbox Code Playgroud)
问题是,为了获取getTableData,我需要一些其他组件的状态.如何在此方法中访问状态对象?
我刚刚在React中查看了HOC.他们很酷.但是,不是简单地包装组件就能达到相同的效果吗?
这个简单的HOC将状态作为属性传递给ComposedComponent
const HOC = ComposedComponent => class extends React.Component {
... lifecycle, state, etc;...
render() {
return (<ComposedComponent {...this.state} />);
}
}
Run Code Online (Sandbox Code Playgroud)
此组件将state作为属性传递给子组件
class ParentComponent extends React.Component {
... lifecycle, state, etc;...
render() {
return (
<div>
{React.cloneElement(this.props.children, { ...this.state })}
</div>
);
}
}
Run Code Online (Sandbox Code Playgroud)
尽管两者之间的使用略有不同,但它们似乎都可以重复使用.
通过this.props.children,HOC和组成组件之间的真正区别在哪里?是否有例子只能使用其中一个?使用HOC是一种更好的做法.这些只是您选择自己喜欢的风味的选择吗?
我有这个:
const ProjectsSummaryLayout = ({projects}) => {
return (
<div className="projects-summary col-md-10">
<h3>Projects</h3>
<ul>
{ projects.map(p => <li key={p.id}>{p.contract.client}</li>) }
</ul>
</div>
)
}
const ProjectsSummary = connect(
state => ({projects: state.projects})
)(ProjectsSummaryLayout)
Run Code Online (Sandbox Code Playgroud)
我得到:
警告:无法为无状态函数组件提供refs(请参阅Connect(ProjectsSummaryLayout)创建的ProjectsSummaryLayout中的ref"wrappedInstance").尝试访问此参考将失败.
它试图告诉我什么?我实际上做错了吗?
我在这里看到关于这个的讨论,但不幸的是我根本不理解结论.
我正在试图弄清楚如何在redux中为商店设置初始状态.我使用https://github.com/reactjs/redux/blob/master/examples/todos-with-undo/reducers/index.js作为示例.我试图修改代码,以便todos初始化了一个值.
const todoApp = combineReducers({
todos,
visibilityFilter
}, {
todos: [{id:123, text:'hello', completed: false}]
})
Run Code Online (Sandbox Code Playgroud)
遵循文档:http://redux.js.org/docs/api/createStore.html
但它不起作用,我不太清楚为什么.
react-redux ×10
reactjs ×9
redux ×6
javascript ×3
react-router ×2
ecmascript-6 ×1
react-hooks ×1
redux-form ×1
redux-thunk ×1