【问题标题】:Destructuring a Object nested inside Array解构嵌套在数组中的对象
【发布时间】:2021-10-04 19:57:52
【问题描述】:

我有以下对象结构

session: {
  expires: String,
  sessionData: {
    user: Object,
    token: String
  }
}

我想在定义这些常量的同一行代码中进行破坏,这些常量是从 react 的钩子中获得的。

const [ session, loading ] = useSession();

我目前正在这样做。有其他选择吗?

 const [ session, loading] = useSession();
 const { user } = session.sessionData;

我想知道这样的事情是否可以做到:

 const [ user: session: {sessionData: user}, loading] = useSession();

【问题讨论】:

  • 您似乎在暗示您要创建一个上下文。查看如何在反应中创建上下文。 reactjs.org/docs/context.html
  • useSession 来自哪个模块?它是否真的返回您的代码所暗示的可迭代? (const [ session, loading ] = useSession();)
  • @GeomanYabes 它来自一个名为 next-auth 的库,是的,该对象是可迭代的,在另一个问题的答案中,我标记了我发现最合适的解决方案。

标签: javascript arrays reactjs typescript destructuring


【解决方案1】:

注意事项:

1.如果sessionDatanullundefined,此代码将出错:

const [{sessionData: { user }}, loading] = useSession();

const useSession = () => [{
  expires: new Date(Date.now() + (3600 * 1000 * 24)),
  sessionData: null
}, false];

const [{ sessionData: {user}}, loading] = useSession();
console.log('user:', user, 'loading:', loading);

2.使用相同的代码,您无法分配内联默认值来修复上述TypeError

const someData = {
  foo: 'foo',
  bar: 'bar'
};

//assign `baz: 'default'` to avoid `TypeError` if `baz` property does not exist
const {foo, bar, baz = 'default'} = someData;
console.log(foo, bar, baz);



//sadly, this doesnt work here.
const useSession = () => [{
  expires: new Date(Date.now() + (3600 * 1000 * 24)),
  sessionData: null
}, false];

const [{ sessionData: {user} = {} }, loading] = useSession();
console.log('user:', user, 'loading:', loading);

也许我遗漏了一些东西,但我无法使用默认值让它工作。我解决此问题的唯一方法是先获取sessionData,然后在使用默认值的同时进行处理。

const useSession = () => [{
  expires: new Date(Date.now() + (3600 * 1000 * 24)),
  sessionData: null
}, false];

//assign {} to `sessionData` if it is undefined
const [{expires, sessionData = {} }, loading] = useSession();
console.log(sessionData); //null

//above default value will still fail if sessionData is null.
// to fix, coalesce to {}
const {user, token} = sessionData || {}; 
console.log(user, token);

3.小心“Gotcha's”

您可能已经注意到上述代码中的|| {} 代码,尽管我们为sessionData 添加了默认值。这是因为默认值仅适用于 undefined,而不适用于 nulls。

同样,最好在useSession 上添加合并,因为如果useSession() 返回nullundefined,您的代码将中断。

const useSession = () => { return null; };

//assign {} to `sessionData` if it is undefined
console.log(useSession()); //null

// useSession()[0], a.k.a. session is undefined
// need to add default since we are destructuring `sessionData` from `session`
const [{ sessionData } = {}, loading] = useSession() || [];

//// this also works but it assigns `sessionData = {}`
//const [{ sessionData = {} } = {}, loading] = useSession() || [];
// wont be doing that since we are proving the next point:

//above default value will still fail since `sessionData` will be undefined
// to fix, coalesce to {}
const {user, token} = sessionData || {}; 
console.log(user, token);

终于

首先获取sessionData 和/或expires(又名session)实际上一点也不差,因为您可能还想获取其他属性,即session.expiressessionData.token 等。它还允许您修复上述问题。

awesome article (Object destructuring best practice in Javascript) 深入讨论了上述说明。花点时间阅读。

【讨论】:

    【解决方案2】:

    你可以这样解构来设置user变量:

    const [{sessionData: { user }}, loading] = useSession();
    

    【讨论】:

    • 我以前也是这样解决的,我觉得是对的!
    【解决方案3】:

    您提供的对象结构无效。我来获取usertoken 的构造如下:

    var a = {
          session: {
            expires: '1d',
            sessionData: {
              user: 'myUser',
              token: 'token'
            }
          }
        }
        
        var {session: {sessionData: {user, token}, expires}} = a
        
        console.log(user, token, expires) // 'myUser token 1d'

    欲了解更多信息,请参阅ES6 deep nested object destructuring

    【讨论】:

    • 对象的结构很好,我只是通过以下方式解决了这个问题,无论如何感谢您的回答。 const [ {sessionData: {user}}, loading] = useSession();
    猜你喜欢
    • 1970-01-01
    • 2022-01-08
    • 2017-01-08
    • 2022-11-20
    • 1970-01-01
    • 2020-09-03
    • 2021-07-16
    • 2021-11-16
    • 2019-06-15
    相关资源
    最近更新 更多